#javascript
This question already has answers here: Что в Javascript значит синтакс ( function(){…} )( param1, param2); ? (7 ответов) Closed 4 года назад. Зачем оборачивать блоки кода на JS в самовыполняющиеся функции?
Ответы
Ответ 1
Переменные, объявленные внутри функции, являются локальными (находятся в её области видимости). Это даёт как минимум 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 уже не является глобальной переменной и не зависит от её изменений. Однако тут не нужно забывать о том, что если переменная является объектом, то изменение значения поля объекта "снаружи" приведёт и к изменению значения поля объекта "внутри".
Комментариев нет:
Отправить комментарий