Что такое конструкция (function() { } )() в JavaScript?
Я хотел бы понять, что означает следующий код:
(function () {
})();
Это похоже на то, что он выполняет ту же функцию, что и document.onload
?
5 ответ(ов)
Это просто анонимная функция, которая выполняется сразу после её создания.
Это похоже на то, как если бы вы присвоили её переменной и использовали бы сразу после этого, только без переменной:
var f = function () {
};
f();
В jQuery есть аналогичная конструкция, о которой вы, возможно, думаете:
$(function(){
});
Это сокращённая форма для привязки события ready
:
$(document).ready(function(){
});
Но вышеуказанные две конструкции не являются IIFE (Immediately Invoked Function Expression).
Немедленно вызываемое функциональное выражение (IIFE) — это конструкция, которая сразу же вызывает функцию. Это означает, что функция выполняется сразу после завершения ее определения.
Вот три более распространенных формулировки:
// Предпочтение Крокфорда – скобки внутри
(function() {
console.log('Добро пожаловать в Интернет. Пожалуйста, следуйте за мной.');
}());
// Пример задающего вопроса, скобки снаружи
(function() {
console.log('Добро пожаловать в Интернет. Пожалуйста, следуйте за мной.');
})();
// Использование оператора восклицания
// https://stackoverflow.com/a/5654929/1175496
!function() {
console.log('Добро пожаловать в Интернет. Пожалуйста, следуйте за мной.');
}();
Если нет особых требований к возвращаемому значению, то можно записать:
!function(){}(); // => true
~function(){}(); // => -1
+function(){}(); // => NaN
-function(){}(); // => NaN
Альтернативно, можно сделать так:
~(function(){})();
void function(){}();
true && function(){ /* код */ }();
15.0, function(){ /* код */ }();
Можно даже записать:
new function(){ /* код */ }
31.new function(){ /* код */ }() // Если нет параметров, последние скобки не обязательны
Этот конструкция называется Immediately Invoked Function Expression (IIFE), что означает, что функция выполняется немедленно. Можно думать об этом как о функции, которая вызывается автоматически, когда интерпретатор достигает этой функции.
Наиболее распространенный случай использования:
Одним из самых распространенных случаев использования является ограничение области видимости переменной, созданной с помощью var
. Переменные, созданные с помощью var
, имеют область видимости, ограниченную функцией, поэтому эта конструкция (которая является оберткой функции вокруг определенного кода) обеспечивает, что область видимости вашей переменной не утечет за пределы этой функции.
В следующем примере count
не будет доступен за пределами немедленно вызываемой функции, то есть область видимости count
не утечет из функции. Вы получите ReferenceError
, если попробуете получить к ней доступ вне немедленно вызываемой функции.
(function () {
var count = 10;
})();
console.log(count); // Reference Error: count is not defined
Альтернатива ES6 (рекомендуется)
В ES6 теперь можно создавать переменные с помощью let
и const
. Обе из них имеют блочную область видимости (в отличие от var
, которая имеет область видимости функции).
Поэтому вместо использования этой сложной конструкции IIFE для уже упомянутого случая использования, вы теперь можете писать намного более простой код, чтобы гарантировать, что область видимости переменной не утечет из вашего желаемого блока.
{
let count = 10;
}
console.log(count); // ReferenceError: count is not defined
В этом примере мы использовали let
для определения переменной count
, что ограничивает count
пределами блока кода, который мы создали с помощью фигурных скобок {...}
.
Я называю это "Curly Jail" (тюрьма в фигурных скобках).
Это выражение означает "выполнить немедленно".
Если я сделаю так:
var val = (function(){
var a = 0; // в области видимости этой функции
return function(x){
a += x;
return a;
};
})();
alert(val(10)); //10
alert(val(11)); //21
Здесь создается немедленно вызываемая функция, которая возвращает другую функцию. Переменная a
инициализируется в 0 и сохраняет своё значение между вызовами, так что при каждом вызове val(x)
к a
добавляется переданное значение x
, и результат возвращается.
Второй пример:
var val = (function(){
return 13 + 5;
})();
alert(val); //18
В этом примере мы также используем немедленно вызываемую функцию, которая сразу возвращает результат вычисления 13 + 5
. Переменная val
получает значение 18, которое выводится в alert. Таким образом, мы сразу получаем результат выполнения выражения, а не возвращаем функцию для дальнейшего использования.
Это объявление анонимной функции, которая затем вызывается сразу же:
(function (local_arg) {
// анонимная функция
console.log(local_arg);
})(arg);
Здесь создаётся анонимная функция, принимающая параметр local_arg
. Затем она вызывается с аргументом arg
, который передаётся в качестве значения для local_arg
. В результате, в консоль будет выведено значение arg
. Этот паттерн часто используется для создания локальной области видимости и избежания глобального загрязнения.
JavaScript: Знак плюс перед функциональным выражением
Как перенаправить на другую веб-страницу?
Как выполнить функцию JavaScript, имея её имя в виде строки
В чем разница между String.slice и String.substring?
Проверка соответствия строки регулярному выражению в JS