IIFE JavaScript

JavaScript Immediately-invoked Function Expressions (IIFE)

Сразу вызываемое выражение функции, которое выполняется, как только оно определено. IIFE можно использовать, чтобы избежать подъема переменных из блоков и не загрязнять глобальный объект.

Следующий синтаксис представляет, как определить выражение функции, вызываемое немедленно:

(функция(){ //… })();

Следующий синтаксис представляет, как определить IIFE с помощью стрелочных функций:

(() => { /* */ })()

Why Use Immediately-invoked Function Expressions (IIFE)

Определите обычную функцию в javascript. Затем движок js добавляет функцию к глобальному объекту.

Следующий пример:

sum function (a, b) {возвращает a + b; }

В веб-браузерах функция sum () представляет собой сумму двух переменных для объекта окна:

console.log (window.sum);

Точно так же, если вы объявляете переменную вне обычной функции, движок js также добавляет переменную к глобальному объекту:

var counter = 10; console.log (window.counter); // 10

В этом синтаксисе часть справа от оператора присваивания (=) является выражением функции. Поскольку функция является выражением, вы можете заключить ее в круглые скобки:

let sum = (function (a, b) {return a + b; });

В этом примере переменная sum называется анонимной функцией, которая складывает два аргумента.

Если вы объявите много глобальных переменных и функций, механизму JavaScript будет выделяться память до тех пор, пока глобальный объект не потеряет область видимости.

В результате сценарий может неэффективно использовать память. Кроме того, наличие глобальных переменных и функций может вызвать конфликты имен.

Следовательно, лучший способ запретить функциям и переменным выделять память глобальному объекту — использовать выражения функций, которые вызываются немедленно.

Также вы можете запустить функцию сразу после ее создания:

let sum = (function (a, b) {return a + b;}) (10, 20); console.log (сумма);

В этом примере переменная sum содержит результат вызова функции.

Следующее выражение называется выражением немедленно вызываемой функции (IIFE), потому что функция создается как выражение и немедленно выполняется:

(функция (a, b) {return a + b;}) (10,20);

Помещая функции и переменные внутри немедленно вызываемого функционального выражения, вы можете избежать их загрязнения глобальным объектом:

(function () {var counter = 0; function sum (a, b) {return a + b;} console.log (sum (10,20)); // 30 }());

Named IIFE

IIFE может иметь имя. Однако его нельзя вызвать снова после выполнения:

(функция с именемIIFE() { //… })();

IIFE starting with a semicolon (;)

Иногда вы можете увидеть IIFE, начинающийся с точки с запятой(;):</p>; (функция() { /* */ })();

В этом синтаксисе точка с запятой используется для завершения оператора в случае, если два или более файла JavaScript слепо объединены в один файл.

Например, у вас может быть два файла my1.js и my2.js, которые используют IIFE:

(функция () {//…}) () (функция(){ //… })()

Если вы используете инструмент пакета кода для объединения кода из обоих файлов в один файл, без точки с запятой (;) объединенный код JavaScript вызовет синтаксическую ошибку.

 

Free eBook: Git Essentials

Ознакомьтесь с нашим практическим руководством по изучению Git с лучшими практиками, общепринятыми стандартами и включенной шпаргалкой. Остановите команды Google для Git и изучите их по-настоящему!

Поскольку этот унарный синтаксис менее распространен и может сбивать с толку разработчиков, он обычно не рекомендуется.

IIFE также могут принимать функциональные аргументы. Мы можем передать переменные в области видимости, как показано ниже:

(function (arg1, arg2) {// Код, который выполняется в вашей функции}) («привет», «мир»);

Теперь, когда мы увидели, как создавать IIFE, давайте посмотрим на типичные ситуации, в которых они используются.

When to Use an IIFE?

Наиболее распространенные варианты использования IIFE:

  • Псевдонимы глобальных переменных
  • Создание частных переменных и функций
  • Циклические асинхронные функции

Aliasing Global Variables

Если у вас есть две библиотеки, экспортирующие объект с тем же именем, вы можете использовать IIFE, чтобы убедиться, что они не конфликтуют в вашем коде. Например, библиотеки jQuery и Cash JavaScript экспортируют $ как главный объект.

Вы можете заключить свой код в IIFE, который передает одну из глобальных переменных в качестве аргумента. Допустим, мы хотим убедиться, что $ относится к объекту jQuery, а не к денежной альтернативе. Вы можете убедиться, что jQuery используется со следующим IIFE:

(function ($) {// Код, который выполняется в вашей функции}) (jQuery);

Creating Private Variables and Functions

Мы можем использовать IIFE для создания частных переменных и функций в глобальной области видимости или любой другой области видимости функции.

Функции и переменные, добавленные в глобальную область видимости, доступны для всех скриптов, загруженных на страницу. Предположим, у нас есть функция generateMagicNumber (), которая возвращает случайное число от 900 до 1000 включительно, а также переменную favouriteNumber в нашем файле JavaScript.

Мы можем написать их так:

functiongenerateMagicNumber () {returnMath.floor (Math.random () * 100) + 900; } console.log («Это ваше магическое число:» + generateMagicNumber ()); var избранное число = 5; console.log («Дважды твое любимое число» + favouriteNumber * 2);

Если мы загружаем другие файлы JavaScript в наш браузер, они тоже получают доступ к функциям generateMagicNumber () и favouriteNumber. Чтобы предотвратить их использование или изменение, мы заключаем наш код в IIFE:

(function () {functiongenerateMagicNumber () {returnMath.floor (Math.random () * 100) + 900;} console.log («Это ваше магическое число:» + generateMagicNumber ()); var favavourNumber = 5; журнал консоли («Дважды ваше любимое число» + favouriteNumber * 2); })();

Он работает так же, но теперь generateMagicNumber () и favouriteNumber доступны только в нашем скрипте.

Asynchronous Functions in Loops

Поведение JavaScript многих удивляет, когда обратные вызовы выполняются в цикле. Например, мы считаем от 1 до 5 в JavaScript, вставляя интервал в 1 секунду каждый раз, когда мы регистрируем сообщение. Наивная реализация была бы такой:

for (var i = 1; i <= 5; i ++) {setTimeout (function () {console.log («Я достиг шага» + i);}, 1000 * i); }

Если вы запустите этот код, вы получите следующий результат:

$ node naiveCallbackInLoop.js Я достиг шага 6 Я достиг шага 6 Я достиг шага 6 Я достиг шага 6 Я достиг шага 6

В то время как выходные данные будут печататься 1 секунду за другой, в каждой строке будет указано, что достигнут шаг 6. Почему?

Когда JavaScript обнаруживает асинхронный код, он откладывает выполнение обратного вызова до завершения асинхронной задачи. Вот как он остается неблокирующим. В этом примере оператор console.log () будет выполнен только по истечении тайм-аута.

JavaScript также создал закрытие для нашего обратного вызова. Замыкания — это комбинация функции и ее объема во время создания. С замыканиями наш обратный вызов может получить доступ к переменной i, даже если цикл for уже завершился.

Однако наш обратный вызов имеет доступ только к значению i во время его выполнения. Поскольку весь код внутри функции setTimeout () был отложен, цикл for завершился с i, равным 6. Вот почему все регистрируют, что они достигли шага 6.

Эту проблему можно решить с помощью IIFE:

for (var i = 1; i <= 5; i ++) {(function (step) {setTimeout (function () {console.log (‘Я достиг шага’ + step);}, 1000 * i);}) (i); }

Используя IIFE, мы создаем новую область видимости для нашей функции обратного вызова. Наш параметр шагов IIFE. Каждый раз, когда вызывается наш IIFE, мы передаем ему текущее значение i в качестве аргумента. Теперь, когда обратный вызов готов к выполнению, его закрытие будет иметь правильное значение шага.

Если мы запустим этот фрагмент кода, мы увидим следующий результат:

$ node iifeCallbackInLoop.js Я достиг шага 1 Я достиг шага 2 Я достиг шага 3 Я достиг шага 4 Я достиг шага 5

Хотя IIFE решает нашу проблему с минимальными изменениями кода, давайте посмотрим, как функции ES6 могут упростить выполнение асинхронного кода в циклах.

Block Scoping with let and const

ES6 добавил ключевые слова let и const для создания переменных в JavaScript. Переменные, объявленные с помощью let или const, находятся в области действия блока. Это означает, что к ним можно получить доступ только в пределах ограничивающего блока — области, заключенной в фигурные скобки { }.

Мы считаем от 1 до 5 с интервалом в 1 секунду, используя ключевое слово let вместо var:

for (let i = 1; i <= 5; i ++) {setTimeout (function () {console.log («Я достиг шага» + i);}, 1000 * i); }

Когда мы запустим этот код, мы получим следующий результат:

$ node es6CallbackInLoop.js Я достиг шага 1 Я достиг шага 2 Я достиг шага 3 Я достиг шага 4 Я достиг шага 5

Теперь, когда переменная i находится в области действия блока, замыкания для нашей функции обратного вызова получают соответствующее значение i при окончательном выполнении. Это более кратко, чем наша реализация IIFE.

Использование let — предпочтительный способ выполнения асинхронных функций в цикле,

Conclusion

Выражение немедленно вызываемой функции (IIFE) — это функция, которая выполняется сразу после определения. Этот шаблон использовался для создания псевдонимов глобальных переменных, создания частных переменных и функций, а также для обеспечения правильного выполнения асинхронного кода в циклах.

Несмотря на популярность, мы видели, как изменения в ES6 могут устранить необходимость использования IIFE в современном JavaScript. Однако освоение этой модели также дает нам более глубокое понимание области видимости и замыкания и будет особенно полезно для поддержки устаревшего кода JavaScript.

javascript # node #

Enough! Show me an IIFE or I am leaving now!

Спасибо за терпение и терпение — самый важный навык, необходимый для освоения JavaScript!

Теперь, когда вы освоили определения функций и выражения функций, давайте погрузимся в секретный мир IIFE. Они бывают в некоторых стилистических вариациях. Давайте сначала рассмотрим вариант, который действительно очень легко понять.

Это мои друзья, это наш дорогой IIFE в действии! Когда вы скопируете этот код и попробуете в консоли браузера, вы увидите предупреждение из кода в строке 2. И это почти все. Никто больше никогда не увидит это предупреждение.

Эта функция умерла вскоре после того, как ожила.

Теперь мы понимаем этот не очень интуитивный синтаксис: я знаю, что вы заметили, что «!» в строке 1; Если бы вы этого не сделали, не волнуйтесь, вы бы заметили сейчас!

  1. Как мы видели ранее, оператор функции всегда начинается с ключевого слова function. Каждый раз, когда JavaScript видит ключевое слово функции как первое слово в допустимом операторе, он ожидает, что будет выполнено определение функции. Итак, чтобы этого не произошло, мы вставляем префикс «!» перед ключевым словом function в строке 1. Это в основном заставляет JavaScript обрабатывать все, что находится после «!» как выражение.
  2. Но самое интересное происходит в строке 3, где мы немедленно выполняем это функциональное выражение.

Итак, у нас есть выражение функции, которое вызывается сразу после его создания. И это, друзья мои, называется IIFE, независимо от стилистической вариации, используемой для достижения этого эффекта.

Вышеупомянутый стилистический вариант можно использовать, заменив «!» также с «+», «-» или даже «~». В принципе можно использовать любой унарный оператор.

Теперь попробуйте в консоли! И играйте с IIFE в свое удовольствие!

Все, что делает первый символ «!», — это превращение этой функции в выражение, а не в оператор / определение функции. И тогда мы немедленно выполняем эту функцию.

Еще один быстрый вариант этого показан ниже:

Опять же, void в основном заставляет функцию обрабатывать как выражение.

Все вышеперечисленные шаблоны полезны, когда нас не интересует значение, возвращаемое IIIF.

Но что тогда, если вы хотите получить возвращаемое значение из IIIF и хотите использовать это возвращаемое значение в другом месте? Читайте ответ!

Оцените статью
Блог о JavaScript