В этом руководстве вы узнаете о JavaScript-функциях с немедленным вызовом (IIFE).
Выражение функции JavaScript, вызываемое немедленно, — это функция, определенная как выражение и выполняемая сразу после создания. Ниже показан синтаксис определения немедленно вызываемого функционального выражения:
(function() {
//...
})();Почему IIFE
Когда вы определяете функцию, механизм JavaScript добавляет функцию к глобальному объекту. Следующий пример:
function add(a,b) {
return a + b;
}В веб-браузерах механизм JavaScript добавляет функцию add() к глобальному объекту window :
console.log(window.add);
Аналогичным образом, если вы объявляете переменную вне функции с помощью ключевого слова var, движок JavaScript также добавляет переменную в глобальный объект:
var counter = 10; console.log(window.counter); // 10
Если у вас много глобальных переменных и функций, движок JavaScript освободит только память, выделенную для них, до тех пор, пока глобальный объект не потеряет свои области видимости.
В результате скрипт может неэффективно использовать память. Кроме того, наличие глобальных переменных и функций, скорее всего, вызовет конфликты имен.
Один из способов предотвратить загрязнение глобального объекта функциями и переменными — использовать немедленно вызываемые функциональные выражения.
В JavaScript у вас могут быть следующие выражения:
'This is a string'; (10+20);
Этот синтаксис правильный, даже если выражения не имеют никакого эффекта. Функция также может быть объявлена как выражение, которое называется функциональным выражением:
let sum = function(a, b) {
return a + b;
}В этом синтаксисе часть справа от оператора присваивания( = ) является функциональным выражением. Поскольку функция является выражением, вы можете заключить ее в круглые скобки:
let sum =(function(a, b) {
return a + b;
});В этом примере на переменную sum ссылаются как на анонимную функцию, которая добавляет два аргумента.
Кроме того, вы можете выполнить функцию сразу после ее создания:
let sum = (function(a, b) {
return a + b;
})(10, 20);
console.log(sum);В этом примере переменная sum содержит результат вызова функции.
Следующее выражение называется немедленно вызываемым функциональным выражением(IIFE), поскольку функция создается как выражение и выполняется немедленно:
(function(a, b) {
return a + b;
})(10, 20);Это общий синтаксис для определения IIFE:
(function() {
//...
})();Обратите внимание, что вы можете использовать функцию стрелки для определения IIFE:
(() = > {
//...
})();Помещая функции и переменные внутри немедленно вызываемого функционального выражения, вы можете избежать их загрязнения в глобальном объекте:
(function() {
var counter = 0;
function add(a, b) {
return a + b;
}
console.log(add(10, 20)); // 30
} ());Именованное выражение
IIFE может иметь имя. Однако его нельзя вызвать снова после выполнения:
(function namedIIFE() {
//...
})();Начинающееся с точки с запятой(;)
Иногда вы можете увидеть IIFE, который начинается с точки с запятой(;):
;(function() {
/* */
})();В этом синтаксисе точка с запятой используется для завершения инструкции в случае, если два или более файла JavaScript слепо объединены в один файл.
Например, у вас может быть два файла lib1.js и lib2.js, которые используют IIFE:
(function() {
// ...
})()(function() {
// ...
})()Если вы используете инструмент для объединения кода из обоих файлов в один файл без точки с запятой ( ; ), объединенный код JavaScript вызовет синтаксическую ошибку.
Функция в действии
Предположим, у вас есть библиотека с именем calculate.js со следующими функциями:
function add(a, b) {
return a + b;
}
function mutiply(a, b) {
return a * b;
}И вы загружаете calculator.js в HTML-документ.
Позже вы также захотите загрузить в тот же документ другую библиотеку JavaScript с именем app.js :
<!DOCTYPE html> <head> <meta charset="UTF-8"> <title>JavaScript IIFE</title> </head> <body> <script src="calculator.js"></script> <script src="app.js"></script> </body> </html>
В app.js также есть функция add() :
function add() {
return 'add';
}Когда вы используете функцию add() в документе HTML, она возвращает строку 'add' вместо суммы двух чисел:
let result = add(10, 20); console.log(result); // 'add'
Это связано с тем, что функция add() в app.js переопределяет функцию add() в библиотеке calculator.js.
Чтобы исправить это, вы можете применить IIFE в calculate.js следующим образом:
const calculator = (function() {
function add(a, b) {
return a + b;
}
function multiply(a, b) {
return a * b;
}
return {
add: add,
multiply: multiply
}
})();IIFE возвращает объект, содержащий методы add и multiply, которые ссылаются на функции add() и multiply(). В документе HTML вы можете использовать библиотеку calculator.js следующим образом:
<!DOCTYPE html> <head> <meta charset="UTF-8"> <title>JavaScript IIFE</title> </head> <body> <script src="js/calculator.js"></script> <script src="js/app.js"></script> <script> let result = calculator.add(10, 20); // add in app.js console.log(result); // 30 console.log(add()); // add in the app.js </script> </body> </html>
calculator.add() вызывает функцию add(), экспортированную с помощью calculator.js, а второй вызов функции add() ссылается на функцию add() в app.js
jQuery и IIFE
В следующем HTML-документе используется библиотека jQuery:
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>JavaScript IIFE - jQuery</title>
</head>
<body>
<h1>jQuery Demo</h1>
<script src="https://code.jquery.com/jquery-3.4.1.slim.js"
integrity="sha256-BTlTdQO9/fascB1drekrDVkaKd9PkwBymMlHOiG+qLI=" crossorigin="anonymous"></script>
<script>
let counter = 1;
$('h1').click(function () {
$(this).text('jQuery Demo' + ' Clicked ' + counter++);
});
</script>
</body>
</html>Когда вы импортируете библиотеку jQuery, вы можете получить доступ ко многим полезным функциям jQuery через объект $ или jQuery. Под капотом jQuery использует IIFE для раскрытия своей функциональности.
Делая это, jQuery просто нужно использовать одну глобальную переменную( $ ), чтобы предоставить массу функций, не загрязняя глобальный объект.
В следующем примере показано, как изменить объект jQuery $ на _ внутри IIFE:
(function (_) {
let counter = 1;
_('h1').click(function () {
_(this).text('jQuery Demo' + ' Clicked ' + counter++);
});
})(jQuery);В этом примере мы передали объект jQuery во IIFE. В функции внутри вместо этого используется аргумент _.
