Когда код JavaScript выполняет часть исполняемого кода, создается соответствующий контекст выполнения.
Для каждого контекста выполнения есть три важных свойства:
- Переменный объект (Variable object, VO)
- Цепочка областей
- this
было объяснено раньшеthis, Сегодня мы поговорим об объемах и цепочках объемов.
объем
Область действия относится к области исходного кода программы, где определяются переменные.
Область действия указывает, как найти переменную, то есть определить права доступа исполняемого в данный момент кода к переменной.
JavaScript использует лексическую область видимости, также известную как статическая область видимости.
Так называемая лексическая область видимости — это область действия кода, которая отражается в процессе написания. После того, как код написан и его не нужно выполнять, определена область действия, которая является так называемой лексической областью действия.
Правила для лексического объема:
- Функции разрешают доступ к данным вне функции (также действует принцип близости)
- Только функции во всей структуре кода могут быть ограничены
- Анализ подъема переменной при первом использовании в рамках области применения
- Если текущая область находит нужную переменную, остановите поиск
*Противоположностью лексической области видимости является динамическая область действия, область действия функции определяется при вызове функции.
var value = 1;
function foo() {
console.log(value);
}
function bar() {
var value = 2;
foo();
}
bar(); // 1
Проанализируйте процесс выполнения:
Для выполнения функции foo сначала проверьте, есть ли значение локальной переменной внутри функции foo, если нет, то по позиции записи найдите код верхнего слоя, то есть значение равно 1, поэтому результат напечатает 1.
Предполагая, что JavaScript использует динамическую область видимости, давайте проанализируем процесс выполнения:
Выполните функцию foo, foo все еще найдут изнутри функции, если есть локальное значение переменной. Если нет, позвоните в функцию с объема, которая является функцией внутренней панели, чтобы найти переменные значения, поэтому результаты будут печатать 2.
См. пример из The Definitive Guide to JavaScript:
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f();
}
checkscope();
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f;
}
checkscope()();
Обе части кода будут печатать:local scope. Поскольку в JavaScript используется лексическая область видимости, область действия функции зависит от того, где она была создана.
Ответ со ссылкой на The Definitive Guide to JavaScript:
Выполнение функций JavaScript использует цепочку областей видимости, которая создается при определении функции. В этой цепочке областей видимости определена вложенная функция f(), а область видимости переменной в ней должна быть локальной переменной.Независимо от того, когда и где выполняется функция f(), эта привязка по-прежнему действительна при выполнении f().
цепочка прицелов
При нахождении переменной, сначала посмотрите в контексте текущего объекта переменного объекта, если он не найден, будет выполняться в контексте переменной объекты, просматривающую от родителя (родитель на лексическом уровне), было найдено переменным объектом глобального Контекст, это глобальный объект. Такая вариабельная цепная цепная объект на множестве контекстов выполнения называется конфигурацией цепи объема.
Атрибут [[scope]] функции здесь специально не вводится, а только как просто проанализировать цепочку областей видимости.
Правила построения цепочки областей видимости следующие:
- Глобальные переменные и объявления функций относятся к цепочке 0-го уровня, и каждый объект занимает позицию
- Когда встречается объявление функции, цепочка расширяется, а уровень расширяется.
- При доступе к переменной сначала загляните внутрь текущей функции, если текущая область видимости не определена, проверьте ее в верхней цепочке
- Это идет вперед и назад до цепочки уровня 0, если нет уровня 0, эта переменная не определена.
Возьмем код в качестве примера:
function func1(){
alert(num);
}
function func2(){
var num=456;
function func3(){
func1();
}
func3();
}
func2();//结果显示:num is not defined
Приведенная выше цепочка областей кода выглядит следующим образом:
Проанализируйте поток выполнения кода:
- Когда программа выполняется в func2, войдите в среду выполнения func2.
- Когда программа выполняется в func3, func1 не находится в контексте func3.
- Вернитесь к области первого уровня, то есть области первого уровня, где находится объявление func3, и оно не найдено.
- Вернитесь к области 0-уровня, где была объявлена func2, и войдите в контекст func1 после его обнаружения.
- Func1 относится к области объема 0 уровней, и может получить доступ к внутреннему объему функции Func1 и объема уровня 0 уровней. Обмен не найден в области функции Func1. Когда он возвращается на объем 0-го уровня, не найден, и ошибка брошена
осторожность:
- Только объявление функции расширит нижнюю цепочку, вызов будет только искать, а не расширять нижнюю цепочку
- Все цепочки могут получить доступ к цепочке 0-го уровня, а цепочка 0-го уровня может получить доступ только к цепочке 0-го уровня.
Связанные серии:Путешествие по построению фундамента с нуля (отличное, постоянное обновление ~)
Если у вас появятся новые знания, пожалуйста, поставьте лайк автору~ Ему срочно нужна поддержка~
Справочная статья: