Замыкания
Рассмотрим замыкания на простейшем примере:
function outer(){
let x = 5;
function inner(){
x++;
console.log(x);
};
return inner;
}
let fn = outer(); // fn = inner, так как функция outer возвращает функцию inner
// вызываем внутреннюю функцию inner
fn(); // 6
fn(); // 7
Поскольку функция outer возвращает функцию inner, то переменная fn будет хранить ссылку на функцию inner. При этом эта функция запомнила свое окружение - то есть внешнюю переменную x. И может её использовать. В этом суть замыканий.
Рассмотрим еще один пример:
function multiply(n){
var x = n;
return function(m){ return x * m;};
}
var fn1 = multiply(5);
var result1 = fn1(6); // 30
console.log(result1); // 30
var fn2= multiply(4);
var result2 = fn2(6); // 24
console.log(result2); // 24
То есть fn1 — это замыкание, которое содержит и внутреннюю функцию function(m){ return x * m;}, и переменную x, которая существовала во время создания замыкания. При создании двух замыканий: fn1 и fn2, для каждого из этих замыканий создается свое окружение. При этом важно не запутаться в параметрах. При определении замыкания: var fn1 = multiply(5); Число 5 передается для параметра n функции multiply. При вызове внутренней функции: var result1 = fn1(6); Число 6 передается для параметра m во внутреннюю функцию: function(m){ return x * m;};.
Также мы можем использовать другой вариант для вызова замыкания:
function multiply(n){
var x = n;
return function(m){ return x * m;};
}
var result = multiply(5)(6); // 30
console.log(result);
Самовызывающиеся функции
Мы также можем создать такие функции, которые будут вызываться сразу при определении.
Такие функции еще называют Immediately Invoked Function Expression (IIFE).
Т.е. функция представленая ниже уже вывела результат в консоль:
(function(){
console.log("Привет мир");
}());
(function (n){
var result = 1;
for(var i=1; i<=n; i++)
result *=i;
console.log("Факториал числа " + n + " равен " + result);
}(4));
Подобные функции заключаются в скобки, и после определения функции идет в скобках передача параметров.