Вы легко поймете, как работает лексическая область видимости, цепочка областей видимости и лексическая среда.

Учебник по лексической сфере

Если вы хотите понять основы области видимости, вы можете прочитать мою 📰 статью об этом, но вот краткий обзор того, что такое область видимости.

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

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

Работа с лексическим объемом

Вы когда-нибудь задумывались, почему вы получаете SyntaxError еще до того, как JavaScript начнет выполнять ваш код, т. е. во время выполнения?

console.log("Will I be executed?"); // This line never get's executed

console.log(answer

// SyntaxError: missing ) after argument list

Это происходит потому, что есть «компиляция» ИЛИ, лучше сказать, парсинг, который происходит до того, как JavaScript запустит наш код. Назовем это временем компиляции.

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

Откуда JavaScript знает, где найти идентификатор в нашем коде? Вот где вступает в действие цепочка областей видимости.

Цепочка областей действия

Во время «компиляции», когда JavaScript видит формальное объявление, он сначала просматривает свою локальную область видимости, чтобы увидеть, было ли оно уже объявлено ИЛИ нет, потому что нет ничего лучше повторного объявления. Если это не так, то JavaScript добавляет его в локальную область видимости.

Вот в чем дело. JavaScript ищет формальное объявление идентификатора, чтобы проверить, существует ли оно ИЛИ нет. Сначала он ищет в своей локальной области, если не найден, то ищет в области своего родителя, если не найден и там, то он будет искать в родительской области родителя, и он будет продолжать этот обход, пока не найдет объявление . Последней областью, в которой он будет проверять, будет глобальная область.

Если он найдет объявление, то путь, пройденный от ссылки к объявлению, будет нашей цепочкой области видимости.

var fish = "🐠";

function getFood() {
  function getFish() {
    console.log(fish); // 🐠
  }

  getFish();
}

getFood();


// Scope chain - getFish -> getFood -> global

Что делать, если он не находит объявление? В этом случае JavaScript не будет знать об идентификаторе и во время выполнения выдаст ReferenceError.

Лексическое окружение

Лексическая среда — это карта ИЛИ словарь, подобная структуре данных, где

  • keys — имя идентификатора
  • значения либо

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

// Lexical environment: Global
var fish = "🐠";

function getFish() {
  // Lexical environment: getFish
  var fish = "🐟";
  return fish;
}

console.log(getFish()); // 🐟
console.log(fish); // 🐠

Глобальное лексическое окружение будет примерно таким:

lexicalEnvironment = {
  fish: '🐠',
  getFish: <ref. to the object>
};

Лексическое окружение имеет ссылку, которая ссылается на лексическое окружение своего родителя. Таким образом, лексическое окружение для getFish будет примерно таким:

lexicalEnvironment = {
  fish: '🐟',
  outer: <outer lexical environment>
};

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

Лексическая область видимости идентификатора — это место, где к нему можно получить доступ во время компиляции. Принимая во внимание, что лексическое окружение — это структура, в которой хранятся идентификаторы и ссылки на лексическое окружение родителя для области видимости.

Что дальше?