JavaScript - Закрытия

Здравствуйте, будущие суперзвезды кодирования! ? Сегодня мы отправимся в увлекательное путешествие в мир JavaScript закрытий. Не беспокойтесь, если это звучит немного пугающе — я обещаю, что к концу этого учебника вы станете экспертами в闭合ностях! Так что возьмите свой любимый напиток, устройтесь поудобнее и lets dive in!

JavaScript - Closures

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

Представьте себе магическую коробку, которая помнит все, что в ней находится, даже после того, как вы ее закрыли. Вот что такое闭合ность в JavaScript!

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

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

function outerFunction(x) {
let y = 10;
function innerFunction() {
console.log(x + y);
}
return innerFunction;
}

let closure = outerFunction(5);
closure(); // Выводит: 15

В этом примере innerFunction является闭合ностью. Она "помнит" значения x и y, даже после того, как outerFunction закончила выполняться.

Лексическая область видимости

Прежде чем мы углубимся в闭合ности, нам нужно понять лексическую область видимости. Это модное слово, которое просто означает, что функция может доступа к переменным из своего внешнего контекста.

let name = "Alice";

function greet() {
console.log("Hello, " + name + "!");
}

greet(); // Выводит: Hello, Alice!

Здесь greet может доступа к переменной name благодаря лексической области видимости. Это похоже на то, что greet видит все в своей окружающей среде.

Вложенная функция

Закрытия часто involve вложенные функции. Давайте рассмотрим пример:

function outer() {
let count = 0;
function inner() {
count++;
console.log(count);
}
return inner;
}

let counter = outer();
counter(); // Выводит: 1
counter(); // Выводит: 2

Здесь inner вложена в outer. Магия происходит потому, что inner помнит переменную count из своего внешнего контекста, даже после того, как outer закончила выполняться.

Возвращающая функция

Один из классных аспектов JavaScript заключается в том, что функции могут возвращать другие функции. Это ключевой аспект闭合ностей.

function multiplier(x) {
return function(y) {
return x * y;
};
}

let double = multiplier(2);
console.log(double(5)); // Выводит: 10
console.log(double(3)); // Выводит: 6

В этом примере multiplier возвращает функцию, которая помнит значение x. Эта возвращенная функция является闭合ностью.

Дилемма счетчика

Давайте рассмотрим распространенную проблему, которую могут решить闭合ности:

function createCounter() {
let count = 0;
return {
increment: function() {
count++;
},
getCount: function() {
return count;
}
};
}

let counter = createCounter();
counter.increment();
counter.increment();
console.log(counter.getCount()); // Выводит: 2

Здесь闭合ность позволяет нам иметь private переменные (count), к которым можно доступить только через предоставленные методы.

Пример: JavaScript Закрытия

Давайте углубимся в более сложный пример, чтобы действительно укрепить наше понимание:

function makeAdder(x) {
return function(y) {
return x + y;
};
}

let add5 = makeAdder(5);
let add10 = makeAdder(10);

console.log(add5(2));  // Выводит: 7
console.log(add10(2)); // Выводит: 12

В этом примере makeAdder создает闭合ность, которая "помнит" значение x. Мы можем создать несколько функций сложения с различнымиpreset значениями.

Пример

Вот еще один практический пример闭合ностей:

function createGreeter(greeting) {
return function(name) {
console.log(greeting + ", " + name + "!");
};
}

let greetHello = createGreeter("Hello");
let greetHi = createGreeter("Hi");

greetHello("Alice"); // Выводит: Hello, Alice!
greetHi("Bob");      // Выводит: Hi, Bob!

Этот пример показывает, как можно использовать闭合ности для создания.customized функций.

Преимущества闭合ности

Закрытия предлагают несколько преимуществ:

  1. Приватность данных
  2. Фабрики функций
  3. Поддержание состояния

Давайте рассмотрим их в таблице:

Преимущество Описание Пример
Приватность данных Закрытия могут создавать private переменные function counter() { let count = 0; return { increment: () => ++count, getValue: () => count }; }
Фабрики функций Создание функций с preset параметрами function multiply(x) { return (y) => x * y; }
Поддержание состояния Отслеживание данных между вызовами функций function createGame() { let score = 0; return { addPoint: () => ++score, getScore: () => score }; }

И вот мы и добрались до конца, друзья! Мы совершили путешествие через страну闭合ностей, от основ до более сложных концепций. Помните, как и любая другая مهра, овладение闭合ностями требует практики. Так что не отчаивайтесь, если это не сработает сразу — продолжайте программировать, продолжайте экспериментировать, и скоро вы будете использовать силу闭合ностей, как настоящий JavaScript маг! ?‍♂️✨

Credits: Image by storyset