На данный вопрос уже ответили: Что в Javascript значит синтакс ( function(){…} )( param1, param2); ? 7 ответов Зачем оборачивать блоки кода на JS в самовыполняющиеся функции?
Ответ
Переменные, объявленные внутри функции, являются локальными (находятся в её области видимости). Это даёт как минимум 3 полезных момента:
"Снаружи" не "достучаться" до того, что объявлено внутри функции.
Не получится случайно затереть глобальную переменную, объявив переменную с таким же именем внутри функции.
Глобальная область видимости не "захламляется" данными, которые не должны быть глобальными.
Самовыполняющаяся функция (Immediately-Invoked Function Expression, IIFE) позволяет воспользоваться этими преимуществами, не создавая глобальную функцию.
var x = 1;
(function() {
var x = 2;
var y = 3;
console.log("In: " + x); //In: 2
console.log("In: " + y); //In: 3
})();
console.log("Out: " + x); //Out: 1
console.log("Out: " + y); //ReferenceError: y is not defined
Например, можно использовать самовыполняющуюся функции для того, чтобы сохранять данные, необходимые для работы функции, и которые при этом нужно хранить между вызовами функции:
var test = (function() {
var count = 0;
return function() {
count++;
console.log("Count: " + count);
};
})();
test(); //Count: 1
test(); //Count: 2
console.log(count); //ReferenceError: count is not defined
Переменная count недоступна в глобальной области видимости, однако доступна внутри возвращаемой функции, так как та объявлена внутри самовыполняющейся функции, и поэтому имеет доступ к её области видимости.
Также самовыполняющаяся функция может "помочь" с сохранением промежуточных значений данных при асинхронном выполнении кода.
Например:
for (var i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i);
}, 1000 * i);
}
Данный код будет выводить в консоль раз в секунду не числа по возрастанию, а число 10, потому что на момент вызова первой функции в setTimeout глобальная переменная i уже будет равна 10 (сначала проходят все итерации цикла, а уже потом вызывается первая функция).
Если же обернуть setTimeout в функцию и передавать ей i в качестве аргумента, то вывод будет от 0 до 9
for (var i = 0; i < 10; i++) {
(function(i) {
setTimeout(function() {
console.log(i);
}, 1000 * i);
})(i);
}
В данном случае переменная i в setTimeout уже не является глобальной переменной и не зависит от её изменений. Однако тут не нужно забывать о том, что если переменная является объектом, то изменение значения поля объекта "снаружи" приведёт и к изменению значения поля объекта "внутри".
Комментариев нет:
Отправить комментарий