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

Руководство к закрытиям JavaScript

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

Автор оригинала: Abhilash Kakumanu.

Вступление

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

В этой статье мы постараемся демистифицировать указанные концепции и обеспечить Простое руководство по закрытиям JavaScript Отказ

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

Сначала давайте посмотрим на официальное определение закрытия MDN:

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

В простых терминах закрытие – это функция, которая имеет доступ к внешней функции. Чтобы понять это, давайте посмотрим на то, как работает область на javaScript.

Область применения в JavaScript

Область Определяет, какие переменные видны или могут быть упомянуты в данном контексте. Область применения широко разделена на два типа – Глобальный объем и Местный охват :

  • Глобальный объем – Переменные, определенные вне функции. Переменные в этом объеме могут быть доступны и изменены из любой точки программы, поэтому название «Global».

  • Местный охват – Переменные, определенные внутри функции. Эти переменные специфичны для функции, в которой они определены, следовательно, названы «локальным».

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

let name = "Joe";

function hello(){
    let message = "Hello";
    console.log(message + " " +name);
}

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

JavaScript использует Лексический навес когда дело доходит до функций областей. Это означает, что объем переменной определяется положением его определения в исходном коде. Это позволяет нам ссыловаться на глобальные переменные в меньших областях. Локальная переменная может использовать глобальную переменную, но вице-версию невозможен.

На

function outer(){
    let x = 10;
    
    function inner() {
        let y = 20;
        console.log(x);
    }
    
    inner();
    console.log(y)
}

outer();

Этот код приводит к себе:

10
error: Uncaught ReferenceError: y is not defined

Внутренний () Функция может ссылаться х Так как он определен в внешний () функция. Тем не менее, console.log (y) Заявление в внешний () Функция не может ссылаться на y переменная, потому что она определена в Внутренний () Область функции.

Кроме того, в этом сценарии:

let x = 10;

function func1(){
   console.log(x);
}

function func2() {
  let x = 20;
  func1();
}

func2();

Выход будет:

10

Когда мы называем func1 () изнутри func2 () у нас есть локально определенная переменная х Отказ Однако эта переменная полностью не имеет значения для func1 () Как это не доступно в func1 () Отказ

Таким образом, func1 () Проверяет, есть ли доступна глобальная переменная с этим идентификатором и использует ее, что приведет к значению 10 Отказ

Закрытие под капотом

Закрытие – это функция, которая имеет доступ к своим переменным родителей даже после возврата внешней функции. Другими словами, закрытие имеет три спецификации:

  • Местный охват – доступ к переменным в собственном объеме
  • Область родительской функции – доступ к переменным в его родителе
  • Глобальный объем – доступ к глобальным переменным

Давайте посмотрим на закрытие на работе, сделав функцию, которая возвращает другую функцию:

function outer() {
    let x = 3
    return function inner(y) {
        return x*y
    }
}

let multiplyByThree = outer();

console.log(multiplyByThree(2));

Это приводит к:

6

Если мы сделаем:

console.log(multiplyByThree);

Мы встретили с:

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

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

  1. внешний () Функция определяется в глобальном объеме.
  2. внешний () вызывается, и он возвращает функцию, которая назначена для MultiNybyTreee Отказ

    1. Новый контекст выполнения создан для внешний () Отказ

      • Переменная х установлен на 3.
    2. Возвращает функцию с именем Внутренний () Отказ
    3. Ссылка на Внутренний () назначен MultiNybyTreee Отказ
    4. Поскольку внешняя функция завершает выполнение, все переменные в его объеме удаляются.
  3. Результат функции вызова MultiplybyTree (2) Зарегистрируется в консоли.

    1. Внутренний () вызывается с 2 как аргумент. Итак, y установлен на 2 Отказ
    2. Как Внутренний () Сохраняет цепочку масштаба своей родительской функции, на момент выполнения он все еще будет иметь доступ к значению х Отказ
    3. Это возвращает 6 который вошел в систему на консоль.

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

Визуализирующие замыкания

Закрытия могут быть визуализированы через консоль разработчиков:

function outer() {
    let x = 3
    return function inner(y) {
        return x*y
    }
}

let multiplyByThree = outside();
console.dir(multiplyByThree);

Выполняя код выше в консоли разработчиков, мы видим, что у нас есть доступ к контексту Внутренний (Y) Отказ При ближайшем инспекции мы можем видеть, что часть ее контекста является [[Назыгрыши]] Массив, который содержит все три спецификации, о которых мы говорили.

LO и вот, на массиве спецификаций содержит масштаб своей родительской функции, который содержит х :

Закрывающий элемент в консоли разработчика

Общие случаи использования

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

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

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

const balance = (function() {
    let privateBalance = 0;

    return {
        increment: function(value){
            privateBalance += value;
            return privateBalance;
        },
        decrement: function(value){
            privateBalance -= value;
            return privateBalance;
        },
        show: function(){
            return privateBalance;
        }
    }
})()

console.log(balance.show()); // 0
console.log(balance.increment(500)); // 500
console.log(balance.decrement(200)); // 300

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

Заключение

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

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