Scope
Одна из самых фундаментальных парадигм почти всех языков программирования — возможность сохранять значения в переменных, а позже – извлекать или менять эти значения. Собственно говоря, возможность хранить значения и извлекать значения из переменных — это то, что дает программе состояние.
Но включение переменных в нашу программу порождает самые интересные вопросы, которые мы теперь можем задать: где эти переменные живут? Другими словами: где они хранятся? И, что более важно, как наша программа их находит, когда нуждается в них?
Понимание области видимости
Чтобы обработать программу var a = 2;
, необходимо:
Движок: отвечает за компиляцию от начала до конца и за выполнение нашей JavaScript программы.
Компилятор: выполняет всю работу по парсингу и генерации кода.
Область видимости: собирает и обслуживает список поиска всех объявленных идентификаторов (переменных) и следит за исполнением строгого набора правил, которые как идентификаторы доступны для кода, выполняемого в текущий момент.
Когда вы видите программу var a = 2;
, вы, вероятнее всего, подумаете о ней как об одном операторе. Движок видит два отдельных оператора: один – который Компилятор обработает во время компиляции, а другой – который Движок обработает во время выполнения.
Первая вещь, которую сделает Компилятор с этой программой – выполнит разбиение на лексемы, которые он затем распарсит в дерево. Но, когда Компилятор доберется до генерации кода, он будет интерпретировать программу несколько по-другому, нежели предполагалось.
Компилятор сделает следующее:
Встретив
var a
, Компилятор просит Область видимости посмотреть, существует ли уже переменнаяa
в коллекции указанной области видимости. Если да, то Компилятор игнорирует это объявление переменной и двигается дальше. В противном случае, Компилятор просит Область видимости объявить новую переменнуюa
в коллекции указанной области видимости.Затем Компилятор генерирует код для Движка для последующего выполнения, чтобы обработать присваивание
a = 2
. Код, который Движок запускает, сначала спрашивает Область видимости, есть ли переменная с именемa
, доступная в коллекции текущей области видимости. Если да, то Движок использует эту переменную. Если нет, то Движок ищет в другом месте.
Если Движок в итоге находит переменную, он присваивает ей значение 2
. Если нет, то Движок выкинет ошибку.
Подводя итоги: для присваивания значения переменной выполняется два отдельных действия: первое, когда Компилятор объявляет переменную (если не была объявлена до этого в текущей области видимости), и второе, когда выполняет код, Движок ищет эту переменную в Области видимости и присваивает ей значение, если находит.
Last updated