[JAVASCRIPT] - Урок 5 - Цепь областей видимости


В этом уроке я хочу рассказать о том, что такое цепь областей видимости.

У нас имеется следующий код:

function b() {
  console.log(user);
}
function a() {
   var user = "qqc";
  b();
}
var user = "golos";
a();

Скрипт почти такой, как и в предыдущем уроке, разве что убрали объявление переменной user из функции b и оставили лишь один вывод в консоль. Как думаете, что отобразится в консоли?

Немного вспомним: когда вызывается функция b, создаётся новый контекст выполнения, кладётся в стек вызовов, а все объявленные переменные отправляются в переменное окружение (variable environment). Но, в нашем случае, переменная u в функции b, где мы хотим её отобразить, не объявлена.

Неожиданно, правда? А где же undefined? Ну или qqc, ведь это было последним присвоением перед вызовом функции b?

В консоли мы увидели golos - значение переменной, "живущей" на глобальном уровне.

Когда мы обращаемся к переменной, JavaScript не просто просматривает переменное окружение в текущем контексте выполнения. Я уже упоминала мельком понятие внешнего окружения.

Получается, когда интерпретатор пытается получить доступ к переменной, он сначала проверяет, есть ли такая переменная в текущем контексте выполения, и, если её нет, отправляется на поиски во внешнее переменное окружение. В нашем случае, на глобальном уровне.

Но почему? Ведь мы функцию b вызываем из функции a, почему внешним окружением стал не контекст выполнения этой функции?

Лексически функция b находится в глобальном контексте выполнения, не внутри функции a. То есть на том же уровне, что и строка var user = 'golos'.

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

Такие ссылки, образующие цепочки, называются цепью областей видимости (scope chain). Напомню, что область видимости - это та часть кода, в которой мы имеем доступ к переменным.

Немного изменим код:

function a() {
  function b() {
    console.log(user);
  }
   var user = "qqc";
  b();
}
var user = "golos";
a();

Мы изменили лексическое окружение функции b.




















Комментарии 0


Чтобы читать и оставлять комментарии вам необходимо зарегистрироваться и авторизоваться на сайте.

Моя страницаНастройкиВыход
Отмена Подтверждаю
100%
Отмена Подтверждаю
Отмена Подтверждаю