Возникли проблемы с пониманием подъема и закрытия? Это потому, что вы не очень хорошо понимаете Scope. Эта статья 101 для Scopes.
Что такое масштаб?
Область — это то, где мы ищем вещи. Итак, что это за вещи? идентификаторы. Области помогают нам организовать эти идентификаторы, избежать конфликтов имен и использовать такие функции, как подъем и закрытие. Кроме того, понимание области действия помогает нам писать лучший код.
В JavaScript используется механизм лексической области видимости, который сегодня используется в большинстве языков. Термин «лексический» происходит от процесса под названием lexing, который происходит во время компиляции для определения областей действия для всех идентификаторов в нашем коде.
Да, время компиляции. JavaScript — это «компилируемый» язык.
Области действия JavaScript являются декларативными, то есть, когда вы помещаете переменную внутрь функции, вы явно указываете JavaScript, что областью действия этой переменной является объемлющая функция.
function myScope() { var articleTopic = "scope"; }
Типы области
В JavaScript есть 3 типа области видимости:
- Глобальный охват
- Объем функций
- Область блока (введена в ES6)
Мы рассмотрим каждый тип и поймем, как их использовать для улучшения шаблонов кодирования.
Глобальный охват
Все, что не находится внутри функционального блока ИЛИ, попадает в глобальную область видимости. В этой области доступны такие объекты, как console
и windows
(в случае браузера). Это последнее место, где JavaScript ищет ваш идентификатор, и если он не находит его здесь, то выдает ReferenceError
.
var food = "🍞"; console.log(food); // 🍞 function eat() { // accessing the global variable console.log("Eating " + food); // Eating 🍞 } eat(); // accessing the global identifier
Не рекомендуется иметь много идентификаторов в вашей глобальной области видимости.
В информатике есть принцип, который называется
🔥
принцип наименьшего воздействия. По сути, это говорит о том, что вы должны держать все в секрете и раскрывать только минимально необходимое.
Это решает 3 основные проблемы:
- Именование коллизий
- Нельзя случайно ИЛИ преднамеренно использовать эту вещь не по назначению
- Вы защищаете себя от будущего рефакторинга
Для этого мы должны использовать области видимости функций и блоков.
Объем функций
Когда вы определяете функцию, она автоматически создает область. Независимо от того, как определена функция.
function eat() { var food = "🍞"; console.log(food); // 🍞 } console.log(food); // ReferenceError: food is not defined
Классы в JavaScript — это синтаксический сахар, в котором используются скрытые функции. Так что они также попадают в категорию области действия.
💡
Совет по улучшению кода —var
используется для определения переменных, которые будут использоваться во всей функции.let
также может достичь того же, но семантическиlet
иconst
следует использовать для областей блоков, аvar
следует использовать для области действия на уровне функций.
Область блока
Проблема с использованием var
в таких местах, как if-else
ИЛИ loop
, заключается в том, что окружение находится вне фигурных скобок. Решение этой проблемы было представлено в ES6, т. е. область блока вместе с let
и const
.
if (true) { let food = "🍞"; console.log(food); // 🍞 } console.log(food); // ReferenceError: food is not defined
Возможно, вы не знаете, что фигурные скобки сами по себе не создают область видимости. Когда внутри него используется let
ИЛИ const
, это неявно делает область действия блока.
💡
Блок не должен быть длиннее 5–6 строк и использоватьlet
иconst
при работе над определением переменных в области блока.
Поместите все свои переменные, определенные с помощью let
и const
, в верхнюю часть области блока, потому что вы не можете получить к ним доступ до их инициализации, иначе вы получите ошибку 💀
TDZ (временная мертвая зона).
Иногда может случиться так, что вам нужна переменная только для нескольких строк кода, и вы определяете переменную в области видимости функции. Вместо этого создайте блок и скопируйте переменную в область действия блока. Например:
function eat() { var food = "🍞"; // Pay for the food { let money = 100; console.log("Food cost: " + money); } // Eat the food console.log("Eating " + food); }
Вложенные области
Области действия могут быть вложены в другие области. Рассмотрим следующий пример кода:
{ // global scope function eat() { // eat scope function bite(person) { // bite scope } } }
Здесь у нас есть 3 области видимости — глобальная, eat
и bite
. Область действия функции bite
находится внутри области действия функции eat
, которая, в свою очередь, находится внутри глобальной области видимости. Самая внутренняя область будет иметь доступ к идентификаторам внешних областей, но не наоборот. Следующий пример демонстрирует это:
var food = "🍞"; function eat() { var food = "🥪"; function bite(person) { console.log(person, food); } bite("👩🍳"); } eat(); // 👩🍳 🥪