У программистов будет отличительный элемент в их интервью, если они продемонстрируют, что они владеют его основными понятиями. Здесь я хочу поделиться своими знаниями, объясняя один из них: замыкания. Я надеюсь, что это поможет вам не быть ослепленным тем, что вы обычно видите в функции этой функции JavaScript.

Как разработчик внешнего интерфейса, я твердо убежден, что вы должны освоить Javascript (известный как Vanilla Javascript), прежде чем начинать изучать любой из его фреймворков, таких как Vue, Angular или React. Если вы доминируете в Javascript, вам точно будет легче изучить любой фреймворк.

Если вы сможете объяснить основные понятия языка своими словами, а не просто повторять его определения наизусть, вы будете другим и, скорее всего, одним из основных кандидатов на следующем собеседовании.

Вот почему здесь я хочу поделиться своими знаниями и опытом, пытаясь глубже изучить одну из основных концепций этого языка программирования: Замыкания.

За свою карьеру я был по обе стороны вакансии: как интервьюер и как интервьюируемый. Один из классических вопросов, которые я слышу в ходе этого процесса, звучит так:

Знаете ли вы, что такое замыкание?

И классический ответ:

Да! Это функция внутри другой функции, которая что-то запоминает.

Некоторые другие добавляют «…вещи в его лексическом объеме». Ниже приведен типичный пример замыкания:

function counter (i) {
  // variable in increaseCounter's lexical scope
  let accumulator = i; 
  
  // function (increaseCounter) inside another function (counter)
  function increaseCounter () {
    // accumulator's value "is remembered" by increaseCounter
    console.log(accumulator);
    accumulator = accumulator + 1;
  }

  // counter returns the increaseCounter function reference
  return increaseCounter;
};

// Here is where you think the closure is created...
const increase = counter(1);
// and then it works:
increase(); // prints 1, then accumulator => 2;
increase(); // prints 2, then accumulator => 3;

И это нормально, это правда. Но вы ослеплены тем, что видите. Возможно, это основной вариант использования замыканий, но это не главная причина, по которой у нас есть замыкания.

Я бы сказал, что замыкание на самом деле является обычной функцией, или, по крайней мере, одним из основных свойств, которыми всегда обладает функция с момента ее объявления. Замыкание — это не сверхспособность, которую функции приобретают только тогда, когда они объявляются внутри другой функции, а затем выполняются вне ее. Функция рождается с этой способностью. У вас есть замыкания даже с функциями, объявленными в глобальной области видимости.

См. следующий пример:

// variable "a" declared in global scope
let a = 1;

// function in global scope, it remembers value of "a" in its lexical scope
function closure1 () {
  console.log(a);
  // "a" gets value of 2 only when closure1 is executed
  a = 2;
}

// "a" changes in global scope (before closure1 and closure2 are executed)
a = 3;

// Another function declared in global scope
function closure2 () {
  // closure2 remembers the last change that "a" had.
  console.log(a); 
} 

// Each function remembers the last value that "a" got before its execution
closure1(); // Prints 3, then changes "a" to 2
closure2(); // Prints 2

Теперь мы можем понять, что лексическая область видимости функции — это просто родительская область действия этой функции, независимо от того, является ли она другой функцией или родителем всех областей видимости (глобальная область видимости) и переменными, объявленными и/или измененными в этой области. область видимости запоминается функциями, объявленными в той же области видимости, когда они выполняются. Однако модифицировать глобальные переменные не рекомендуется, поэтому мы обычно видим использование замыканий, как в первом примере: функция внутри другой функции.

Есть много способов использовать замыкания: у нас могут быть вложенные замыкания, замыкания внутри циклов, даже с асинхронными элементами, а также некоторые передовые методы, шаблоны и хорошие практики программирования, основанные на этой способности, такие как запоминание для повышения производительности или шаблоны модулей для эмулировать частные методы, но это темы, которые уже освещены во многих сообщениях здесь, в среде.

И вот оно. Я надеюсь, что вы нашли это полезным. Спасибо за чтение.