Автор оригинала: FreeCodeCamp Community Member.
Уильям Считается
Закрытия JavaScript являются важными, но как известно, запутавшаяся концепция. Нет никаких сбежаков – если вы хотите расти как разработчик, вам нужно понимать, какие закрытия и как их использовать.
Не позволяйте модному названию напугать вас – как только вы играете с закрытыми, вы понимаете, что на самом деле не так много для них.
Давайте начнем с чего-то простого:
1 function sayGreeting(greeting) { 2 3 return function(name) { 4 5 console.log(greeting + " " + name); 6 } 7 8 }
Вы сразу заметите, что наша функция САЮЧЕНИЕ, Возвращает другую функцию. Я могу сделать это в JavaScript, потому что функции считаются Первый класс, Это означает, что их можно пропустить как и другие типы данных, такие как номер, строка или логическое значение. Это может сделать для некоторых интересных синтаксисов:
1 function sayGreeting (greeting) { 2 3 return function (name) { 4 5 console.log (greeting + " " + name); 6 } 7 8 } 9 sayGreeting("Hello")("William");
Так что вы ожидаете увидеть в консоли, когда мы запустим этот код? Подумайте об этом на мгновение, а затем посмотрите на изображение ниже.
Если вы догадались «Привет Уильям», вы правы. Давай и дайте себе похлопывание на спину. Теперь давайте приблизимся к Зачем.
sayGreeting("Hello")("William");
Помните, что САЮЧЕНИЕ Возвращает функция. Как мы упоминали ранее, функции в JavaScript являются первоклассными, и могут быть переданы как любая другая структура данных. Так когда SAYGREETING («HELLO») вызывается Впервые он выполняется и возвращает анонимную функцию. Возвращенная функция также может быть вызвана, и именно поэтому вы видите второй набор скобок: SAYGREETING («HELLO») («Уильям»)
Чтобы сделать это немного легче следовать, давайте немного изменим код, установив первый вызов переменной:
1 function sayGreeting (greeting) { 2 3 return function(name) { 4 5 console.log(greeting + " " + name); 6 } 7 8 } 9 10 var sayHello = sayGreeting("Hello"); 11 sayHello("William");
Если вы запустите это в вашей консоли, вы получите тот же результат, что и раньше. Но как SAYHELLO («Уильям») знает о ценности параметра приветствие от Сэмитед функция? Чтобы понять это, нам нужно немного глубже.
Всякий раз, когда вызывается функция, память откладывается для этой функции и его содержимого, которая придерживается даже после завершения выполнения функции. Мы можем визуализировать это, упаковывая Сайхелло Переменная с Console.dir ()
1 function sayGreeting(greeting) { 2 3 return function(name) { 4 5 console.log(greeting + " " + name); 6 } 7 8 } 9 10 var sayHello = sayGreeting("Hello"); 11 12 console.dir(sayHello); 13 sayHello("William");
Вы увидите в консоли, что переменная Сайхелло это анонимная функция, и в пределах его объема есть C Люди с Имя: значение пара,
Приветствие: “Привет”
Это должно выглядеть знакомым, так как «приветствие» – это имя параметра функции SAYGRETING (приветствие) {…} в строке 1, а «Hello» была строкой, которую мы передали в него, когда мы впервые вызваны функцией в строке 10. Затем память откладывались для этих значений и доступен как внешняя ссылка Когда мы вызываем функцию на линии 13.
Чтобы помочь визуализировать это, выписывайте тело Сайхелло Функция, как это выполняется в строке 13.
1 function (name) { 2 3 console.log (greeting + " " + name); 4 }
Строка «Уильям» передается для параметра имени, то в строке 3 Console.log ( Приветствие + “” + Название ) выполняется.
Затем он ищет значения приветствие и Имя Отказ
Наша функция находит значение для Имя : «Уильям». Но это не имеет значения для приветствие Отказ Итак, теперь пришло время пойти на рыбалку, и он смотрит на его внешнюю ссылку (где он находится с точки зрения лексической области) в попытке найти значение для приветствия.
Другими словами, это помнит, где он был явно написан в коде, который является внутри функции сайеритгинга.
1 function sayGreeting(greeting) { 2 3 return function(name) { 4 5 console.log(greeting + ' ' + name); 6 } 7 8 }
Когда он находит значение приветствие В его внешней ссылке мы ссылаемся на это как закрытие на внешняя переменная, а когда это происходит у вас закрытие Отказ
Это было не так плохо, это было?
Это очень простой пример, но даже в сложных приложениях правила остаются прежними. Всякий раз, когда функция не может найти значение чего-то внутри самого себя, он будет следовать за цепочкой объема в зависимости от цепочки (или в зависимости от того, как вы его представите) и найдите это значение для создания закрытия.