Полный цикл в digital

Замыкания и функции IIFE

Замыкания

Замыкание (closure) представляют собой конструкцию, когда функция, созданная в одной области видимости, запоминает свое лексическое окружение даже в том случае, когда она выполняет вне своей области видимости. Замыкание технически включает три компонента:

  1. внешняя функция, которая определяет некоторую область видимости и в которой определены некоторые переменные - лексическое окружение
  2. переменные (лексическое окружение), которые определены во внешней функции
  3. вложенная функция, которая использует эти переменные
// внешняя функция
function outer(){   
// некоторая переменная
var n;     
// вложенная функция       
return inner(){     
// действия с переменной n
}
}

Рассмотрим замыкания на простейшем примере:

function outer(){
let x = 5;
function inner(){
x++;
console.log(x);
};
return inner;
}
// fn = inner, так как функция outer возвращает функцию inner
let fn = outer();   
// 6
fn();  
// 7 
fn();
// 8   
fn();

Здесь функция outer задает область видимости, в которой определены внутренняя функция inner и переменная x. Переменная x представляет лексическое окружение для функции inner. В самой функции inner инкрементируем переменную x и выводим ее значение на консоль. В конце функция outer возвращает функцию inner.

Далее вызываем функцию outer:

let fn = outer();

Поскольку функция outer возвращает функцию inner, то переменная fn будет хранить ссылку на функцию inner. При этом эта функция запомнила свое окружение - то есть внешнюю переменную x.

Далее мы фактически три раза вызываем функцию inner, и мы видим, что переменная x, которая определена вне функции inner, инкрементируется:

// 6
fn();  
// 7 
fn();  
// 8 
fn();

То есть несмотря на то, что переменная x определена вне функции inner, эта функция запомнила свое окружение и может его использовать, несомотря на то, что она вызывается вне функции outer, в которой была определена. В этом и суть замыканий.

Рассмотрим еще один пример:

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);
// 24
var result2 = fn2(6); 
// 24
console.log(result2);

Итак, здесь вызов функции multiply() приводит к вызову другой внутренней функции. Внутренняя же функция:

function(m){ return x * m;};

Запоминает окружение, в котором она была создана, в частности, значение переменной x.

В итоге при вызове функции multiply определяется переменная fn1, которая и представляет собой замыкание, то есть объединяет две вещи: функцию и окружение, в котором функция была создана. Окружение состоит из любой локальной переменной, которая была в области действия функции multiply во время создания замыкания.

То есть 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;};
}
// 30
var result = multiply(5)(6); 
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));
Заполните форму уже сегодня!
Для начала сотрудничества необходимо заполнить заявку или заказать обратный звонок. В ответ получите коммерческое предложение, которое будет содержать индивидуальную стратегию с учетом требований и поставленных задач
Работаем по будням с 9:00 до 18:00. Заявки, отправленные в выходные, обрабатываем в первый рабочий день до 12:00.
Спасибо, ваш запрос принят и будет обработан!
Эйч Маркетинг