Возникли проблемы с пониманием подъема и закрытия? Это потому, что вы не очень хорошо понимаете 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(); // 👩‍🍳 🥪

Что дальше?