Рубрики
Без рубрики

Учебник закрытия JavaScript – с примером пример закрытия JS

Закрытия – многие из вас JavaScript Devs, вероятно, услышали этот термин раньше. Когда я начал свое путешествие с JavaScript, я часто столкнулся с закрытыми. И я думаю, что они одна из самых важных и интересных концепций в JavaScript. Вы не думаете, что они интересны? Это часто случается, когда вы не понимаете

Автор оригинала: FreeCodeCamp Community Member.

Закрытие – Многие из вас JavaScript Devs, вероятно, услышали этот термин раньше. Когда я начал свое путешествие с JavaScript, я часто столкнулся с закрытыми. И я думаю, что они одна из самых важных и интересных концепций в JavaScript.

Вы не думаете, что они интересны? Это часто бывает, когда вы не понимаете концепцию – вы не найдете это интересно. (Я не знаю, это произойдет с тобой или нет, но это дело со мной).

Таким образом, в этой статье я постараюсь сделать замыкание интересными для вас.

Прежде чем идти в мир закрытия, давайте сначала понять Лексический навес Отказ Если вы уже знаете об этом, пропустите следующую часть. В противном случае прыгайте в него, чтобы лучше понять замыкание.

Лексический охват

Вы можете думать – я знаю местные и глобальные масштабы, но то, что черт возьми, лексическая область? Я отреагировал так же, когда я услышал этот термин. Не беспокоиться! Давайте приблизимся.

Это просто, как два других области:

function greetCustomer() {
    var customerName = "anchal";
    function greetingMsg() {
	  console.log("Hi! " + customerName); // Hi! anchal
    }
   greetingMsg();
}

Из вышеуказанного выхода вы можете видеть, что внутренняя функция может получить доступ к переменной внешней функции. Это лексическое определение навеса, где объем и значение переменной определяют, где она определена/создана (то есть его положение в коде). Понятно?

Я знаю, что последний бит мог смутить вас. Так что позволь мне взять тебя глубже. Знаете ли вы, что лексическое обременение также известно как Статический навес ? Да, это другое имя.

Есть также Динамический навес который поддерживает некоторые языки программирования. Почему я упомянул динамическую область? Потому что это может помочь вам лучше понять лексику.

Давайте посмотрим на некоторые примеры:

function greetingMsg() {
  console.log(customerName);// ReferenceError: customerName is not defined
}

function greetCustomer() {
   var customerName = "anchal";
   greetingMsg();
}

greetCustomer();

Согласны ли вы с выходом? Да, это даст ссылочную ошибку. Это потому, что обе функции не имеют доступа к объему друг друга, поскольку они определены отдельно.

Давайте посмотрим на другой пример:

function addNumbers(number1) {
  console.log(number1 + number2);
}

function addNumbersGenerate() {
  var number2 = 10;
  addNumbers(number2);
}

addNumbersGenerate();

Вышеуказанный вывод будет 20 для динамически выделенного языка. Языки, которые поддерживают лексику, дадут SharmerRor: Number2 не определен Отказ Почему?

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

Его название самоуверенно – «динамическое» означает изменения. Область и ценность переменной могут быть разными, поскольку она зависит от того, где называется функция. Смысл переменной может измениться во время выполнения.

Получил суть динамической области? Если да, то просто помните, что лексическое определение на его противоположном.

В лексической области, поиск проходит в локальной функции в первую очередь, затем он входит в функцию, внутри которой что Функция определена. Затем он ищет в функции, внутри которой что Функция определена и так далее.

Итак, Лексический или Статический навес означает, что объем и значение переменной определяют от того, где она определена. Это не меняется.

Давайте снова посмотрим на вышеприведенный пример и попытайтесь выяснить вывод самостоятельно. Только один поворот – объявить №2 на вершине:

var number2 = 2;
function addNumbers(number1) {
  console.log(number1 + number2);
}

function addNumbersGenerate() {
  var number2 = 10;
  addNumbers(number2);
}

addNumbersGenerate();

Вы знаете, что будет вывод?

Правильно – это 12 для лексически лексических языков. Это потому, что во-первых, он смотрит в addnumbers Функция (самая внутренняя область) затем она ищет внутрь, где эта функция определена. Как это получает №2 Переменная, что означает выход 12.

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

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

Что такое закрытие?

Давайте посмотрим на определение закрытия:

Ждать! Это определение закрытия или лексической области? Оба определения выглядят одинаково. Как они разные?

Ну вот почему я определил лексику навесом выше. Потому что замыкание связаны с лексическим/статическим навесом.

Давайте снова посмотрим на свое другое определение, которое скажет вам, как отличаются закрытыми.

Или же,

Смущенный? Не волнуйтесь, если вы еще не получили смысл. У меня есть примеры, чтобы помочь вам лучше понять. Давайте изменим первый пример лексической области:

function greetCustomer() {
  const customerName = "anchal";
  function greetingMsg() {
    console.log("Hi! " + customerName);
  }
  return greetingMsg;
}

const callGreetCustomer = greetCustomer();
callGreetCustomer(); // output – Hi! anchal

Разница в этом коде заключается в том, что мы возвращаем внутреннюю функцию и выполняем ее позже. На некоторых языках программирования локальная переменная существует во время выполнения функции. Но как только функция выполнена, эти локальные переменные не существуют, и они не будут доступны.

Здесь, однако, сцена отличается. После выполнения родительской функции внутренняя функция (возвращенная функция) может все еще может получить доступ к переменным родительской функции. Да, вы догадались правильно. Замыкание – это причина.

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

Чтобы лучше почувствовать это, давайте будем использовать dir () Способ консоли, чтобы посмотреть в список свойств CallGreeTCustomer :

console.dir(callGreetCustomer);

Из вышеуказанного изображения вы можете увидеть, как внутренняя функция сохраняет свою родительскую область ( Consuitername ), когда GreetCustomer () выполняется. А позже он использовал Индивидуальное использование Когда CallGreeTCustomer () был казнен.

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

Так, что дальше? Давайте сделаем эту тему более интересной, глядя на разные примеры.

Примеры закрытия в действии

function counter() {
  let count = 0;
  return function() {
    return count++;
  };
}

const countValue = counter();
countValue(); // 0
countValue(); // 1
countValue(); // 2

Каждый раз, когда вы звоните CountValue , значение переменная подсчета увеличивается на 1. ждать – вы думаете, что стоимость подсчета 0?

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

Чувствую себя немного яснее сейчас? Давайте посмотрим на другой пример:

function counter() {
  let count = 0;
  return function () {
    return count++;
  };
}

const countValue1 = counter();
const countValue2 = counter();
countValue1();  // 0
countValue1();  // 1
countValue2();   // 0
countValue2();   // 1

Я надеюсь, что вы догадались правильный ответ. Если нет, вот причина. Как CountValue1 и CountValue2 оба сохраняют свои собственные лексические масштабы. Они имеют независимые лексические условия. Вы можете использовать dir () Чтобы проверить [[Назыгрыши]] ценность в обоих случаях.

Давайте посмотрим на третий пример.

Это немного другое. В нем мы должны написать функцию для достижения вывода:

const addNumberCall = addNumber(7);
addNumberCall(8) // 15
addNumberCall(6) // 13

Простой. Используйте свои новобранные знания о закрытии:

function addNumber(number1) {
  return function (number2) {
    return number1 + number2;
  };
}

Теперь давайте посмотрим на несколько хитрых примеров:

function countTheNumber() {
  var arrToStore = [];
  for (var x = 0; x < 9; x++) {
    arrToStore[x] = function () {
      return x;
    };
  }
  return arrToStore;
}

const callInnerFunctions = countTheNumber();
callInnerFunctions[0]() // 9
callInnerFunctions[1]() // 9

Каждый элемент массива, который хранит функцию, даст вам вывод 9. Вы угадаете правильно? Я надеюсь, но все же позвольте мне рассказать вам причину. Это из-за поведения закрытия.

Закрытие хранит Ссылка , не ценность. Первый раз, когда цикл работает, значение x равно 0. Тогда второй раз x равно 1, и так далее. Поскольку закрытие хранит ссылку, каждый раз, когда цикл работает, это изменяет значение x. И наконец, значение X будет 9. Итак, CallInnerfunctions [0] () дает вывод 9.

Но что, если вы хотите вывести от 0 до 8? Простой! Используйте закрытие.

Подумайте об этом, прежде чем смотреть на решение ниже:

function callTheNumber() {
  function getAllNumbers(number) {
    return function() {
      return number;
    };
  }
  var arrToStore = [];
  for (var x = 0; x < 9; x++) {
    arrToStore[x] = getAllNumbers(x);
  }
  return arrToStore;
}

const callInnerFunctions = callTheNumber();
console.log(callInnerFunctions[0]()); // 0
console.log(callInnerFunctions[1]()); // 1

Здесь мы создали отдельный объем для каждой итерации. Вы можете использовать Console.dir (Arrtostore) Чтобы проверить значение X в [[Назыгрыши]] для разных элементов массива.

Это оно! Я надеюсь, что теперь вы можете сказать, что вы найдете замыкание интересными.

Чтобы прочитать мои другие статьи, проверьте мой профиль здесь.