What is the output of this code?
var a = 5; // (1)
!function(x) { // (2)
a = x; // (3)
}(7); // (4)
console.log(a); // a = 7 (5)
(1) - объявляется переменная a
с помощью ключевого слова var
(смотри ссылку ниже). На этой же строчке она инициализируется, то есть переменной присваивается значение, равное 5. Наша переменная - это глобальная (видна в глобальной области видимости) переменная (смотри ссылку ниже)
(2) - Это IIFE - immediately-invoked function expressions (смотри ссылку и примеры ниже)
(3) - Мы присваиваем переменной a
(БЕЗ ключевого слова var
) в теле функции (то, что между фигурными скобками) значение аргумента (а впоследствии параметра) функции - x
. Анализатор пробегается по коду и понимает, что глобальной переменной a
, равной 5, присваивается аргумент x
, значение которого будет известно чуть ниже (смотри пункт 4). То есть значение будет перезаписано. В ячейке памяти, на которую ссылается переменная a
, будет уже другое значение. Потому что это немедленновызываемая функциональное выражение
(4) - функции пробрасывается сразу параметр x
со значением 7. Это значит, что переменной a
переприсваивается значение, у неё теперь новое значение, равное 7
(5) - Выводится в консоль браузера значение глобальной переменной a
, которое равно 7
По IIFE: Такая запись (функции) означает, что это это IIFE - immediately-invoked function expressions. То есть немедленно исполняемое функциональное выражение("выражение" объяснить можно отдельно).
IIFE можно записать несколькими способами:
(function() {
alert("Parentheses around the function");
})();
(function() {
alert("Parentheses around the whole thing");
}());
!function() {
alert("Bitwise NOT operator starts the expression");
}();
+function() {
alert("Unary plus starts the expression");
}();
Можно скопировать то, что выше в консоль браузера и посмотреть на результаты. То есть эти функции объявляются и сразу же выполняются (а именно тело функций - что между фигурными скобками) выполнятся сразу. Потому и "немедленно исполняемое" в названии IIFE (immediately-invoked)
Для проверки можно добавить несколько выводов переменной в консоль до и после инициализации внутри функции:
var a = 5;
!function(x) {
console.log('before initialization', a); // before initialization 5
a = x;
console.log('after initialization', a); // after initialization 7
}(7);
Ссылки с полезной информацией для лучшего понимания того почему и как этот пример работает
- Ключевое слово
var
- Что такое и как рботает IIFE
- Что такое глобальный объект
- Про функции, про области видимости, про локальные переменные
- Function Expression