Один мудрый человек однажды сказал
«Чтобы стать гуру в JavaScript, вам нужно освоить закрытие».
Жил-был сумасшедший архитектор, который решил построить подземный отель. Он построил этот отель с двумя подземными этажами, а именно с подвалом 1 (B1) и подвалом 2 (B2). На каждом этаже есть две комнаты, одна комната для проживания, а другая - для развлечений.
На первом этаже находится рецепция и кафетерий. На уровне B1 находится комната для настольного тенниса. На уровне B2 есть комната для игры в снукер.
Есть лифт, который работает только с картой доступа. Есть одно интересное правило этого отеля, которое нельзя нарушать ни при каких обстоятельствах. Правило в том, что вы можете получить доступ.
- Первый этаж (рецепция и кафетерий).
- Этаж, который вы забронировали, и
- Любая развлекательная комната до вашего этажа.
Однажды этаж B1 забронировал Джон Сноу, а этаж B2 - Кхалиси. По правилу любой желающий может получить доступ к цокольному этажу. Джон может получить доступ к комнате для настольного тенниса, но не может получить доступ к комнате для игры в снукер. Khaleesi может получить доступ к комнате для настольного тенниса, а также в комнате для игры в снукер.
На первом этаже во время ужина Кхалиси спросил Джона о закрытии JavaScript. Как обычно, Джон этого не знал. Он спросил, что такое закрытие в JavaScript? Затем Халиси начинает объяснять.
«Короткий ответ: это просто внутренняя функция. Но на самом деле это намного больше, чем просто внутренняя функция ».
Основы закрытия
1. Доступ к переменным разного объема.
Наша гостиница работает как закрытие. Khaleesi может получить доступ к цокольному этажу, комнате для настольного тенниса и ее этажу. Точно так же при закрытии мы можем получить доступ к локальной, внешней и глобальной области.
2. Доступ к переменным после выполнения.
В случае некоторых других языков, когда функция выполняется, все ее локальные переменные недоступны. Но в случае закрытия JavaScript, даже если функция была выполнена, она все еще содержит ссылки на свои локальные переменные.
В примере выше calculateSalary()
- это закрытие. Когда выполняется line 10
, вызывается getSalary()
и значение baseSalary
рассматривается как 100. Этот вызов функции возвращает определение внутренней функции (закрытие). Это определение функции присвоено переменной monthlySalary
. На данный момент закрытие еще не выполнено.
Когда выполняется line 11
, выполняется закрытие. Это закрытие (внутренняя функция) имеет доступ к локальным переменным, таким как hraAmount
, переменным внешней области видимости, таким как transportAmount
, глобальным переменным, таким как sodexoAmount
.
3. частные методы
В JavaScript нет частных методов, но мы можем добиться этого эффекта с помощью Closure. В этом случае calculateSalary
- частный метод.
4. Собственные примеры закрытия
- setTimeout
Функциональная часть setTimeout
- не что иное, как закрытие. Он запускается по истечении указанного времени.
- setInterval
Подобно setTimeout
, функциональная часть setInterval
является закрытием. Он запускается каждый раз, когда указанный интервал завершается.
- Функции прослушивателя событий
Каждая функция прослушивателя событий в JavaScript - это закрытие. В примере выше addUser
функция является закрытием.
- Функции обратного вызова http API
http API может иметь несколько функций обратного вызова. Каждая функция обратного вызова API в JavaScript - это закрытие.
5. Закрытие внутреннего цикла - анонимное закрытие.
До ES6
, когда мы использовали замыкание внутри любого цикла, мы должны были быть особенно осторожными. Во время итерации в любом цикле неправильный счетчик будет сопоставлен с закрытием, если мы не позаботимся. Это может создавать ошибки в нашей программе. Есть несколько способов решить эту проблему. Всякий раз, когда мы используем замыкание внутри цикла, я рекомендую закрыть это закрытие анонимным закрытием и передать счетчик анонимному закрытию.
6. Минусы закрытия
- Когда слишком много вложений замыканий, становится очень трудно понять код.
- Когда слишком много вложений замыканий, отладка проблемы внутри таких замыканий становится кошмаром.
- Если мы создадим замыкания без необходимости, это может вызвать проблемы с производительностью.
Заключение:
Замыкание - очень интересная и широко используемая концепция JavaScript. Но при его использовании нужно проявлять особую осторожность.