предисловие
Слово всегда слышно в индустрии программированияконтекст выполнения. Так что же этоконтекст выполненияШерстяная ткань?
Эта статья в основном знакомитjavascript
Контекст выполнения в , прочитав его, можно понять:
- тип контекста выполнения
- Особенности контекста выполнения
- стек выполнения
- Жизненный цикл контекста выполнения
концепция
Во-первых, давайте представим, что такое «контекст выполнения».
Например, в жизни одни и те же слова могут иметь разное значение в разных случаях, а поводом для речи является контекст, в котором мы говорим.
Точно так же и в программировании при «интерпретации» языка программирования он также должен находиться в определенном контексте.javascript
контекст выполнения в .
Вкратце в одном предложении:
Контекст выполнения
javascript
Абстракция среды, в которой анализируется и выполняется код.
тип контекста выполнения
существуетjs
, контекст выполнения делится на следующие три типа:
-
глобальный контекст выполнения: есть только один объект браузера (т.е.
window
объект),this
Указывает на этот глобальный объект. - контекст выполнения функции: их бесчисленное множество, только в функцииназыватьсябудетСоздайте, при каждом вызове функции создается новый контекст выполнения.
-
Контекст выполнения функции Eval:
js
изeval
Функция, которая выполняет код внутри себя, создает свой собственный контекст выполнения, который редко используется и не рекомендуется.
Характеристики контекста выполнения
- Однопоточный, работает только в основном потоке;
- Синхронное выполнение, выполняемое последовательно сверху вниз;
- Существует только один глобальный контекст, который
window
объект; - Контекст выполнения функции не ограничен;
- Каждый раз при вызове функции создается новый контекст выполнения.
Как JS управляет несколькими контекстами выполнения
Из приведенного выше введения мы знаемjs
Код может генерировать бесконечное количество контекстов выполнения во время выполнения, так как же он управляет этими контекстами выполнения?
В то же время из-заjs
Он однопоточный, поэтому две вещи не могут выполняться одновременно и должны выполняться одна за другой, так в каком же порядке выполняется так много контекстов выполнения?
стек выполнения
Далее, чтобы ответить на поставленные выше вопросы, управление несколькими контекстами выполнения зависит отстек выполненияТакже известен какстек вызовов.
Функции: Структура «последний пришел – первый ушел» (LIFO).
эффект: сохраняет все контексты выполнения во время выполнения кода.
(LIFO
: last-in, first-out
, аналогично тому, как положить мяч в ведерко для пинг-понга, тот, кого кладут первым, вынимают последним)
js
При первом исполненииглобальный контекст выполненияи поместите его в стек.
Всякий раз, когда вызывается функция, движок создает новую функцию для этой функции.контекст выполнения функцииЗатем поместите его в стек.
Когда функция на вершине стека выполняется, функция, соответствующаяконтекст выполненияиз стека выполненияpop
out, то управление контекстом переходит к следующему контексту выполнения.
Возьмите следующий пример 🌰:
var a = 1; // 1. 全局上下文环境
function bar (x) {
console.log('bar')
var b = 2;
fn(x + b); // 3. fn上下文环境
}
function fn (c) {
console.log(c);
}
bar(3); // 2. bar上下文环境
Как показано ниже:
Жизненный цикл контекста выполнения
Жизненный цикл контекста выполнения также очень легко понять, он разделен на три фазы:
- создать сцену
- этап выполнения
- фаза разрушения
создать сцену
существуетсоздать сцену, в основном есть несколько вещей:
- Конечноthisценность, то естьсвязать это (This Binding);
- Лексическое окружение) компонент создан;
- Компонент **VariableEnvironment** создан.
Одна картинка удобна для понимания🤔
Некоторые учебники также любят использовать псевдокод для реализации:
ExecutionContext = {
ThisBinding = <this value>, // 确定this
LexicalEnvironment = { ... }, // 词法环境
VariableEnvironment = { ... }, // 变量环境
}
This Binding
Из приведенного выше введения мы знаем, что фактическая разработка в основном использует два контекста выполнения:Глобальныйа такжефункция, затем привязатьthis
Также разные в этих двух контекстах.
- В глобальном контексте выполнения
this
Относится к глобальному объекту, на который указывает среда браузера.window
объект,nodejs
указывая на этот файлmodule
объект. - Контекст выполнения функции более сложен,
this
Значение зависит от того, как вызывается функция, а именно: привязка по умолчанию, неявная привязка, явная привязка,new
Привязки, стрелочные функции.
Лексическое окружение
Как показано выше,Лексическое окружениесостоит из двух частейсочинениеиз:
- Экологические записи: фактическое место, где хранятся объявления переменных и функций;
- Ссылка на внешнюю среду: Используется для доступа к внешней лексической среде.
такой же,Лексическое окружениеТакже есть два основных вида:
-
глобальная среда: владеет глобальным объектом (объектом окна) и всеми связанными с ним свойствами и методами (такими как методы массива)
splice、concat
и т. д.), а также включает определяемые пользователем глобальные переменные.глобальная средаОтсутствует ссылка на внешнюю среду, то есть ссылка на внешнюю средуnull
. -
функциональная среда: Пользовательские переменные и функции в функциях хранятся вЭкологические записи, включая
arguments
объекта, тогда как ссылка на внешнюю среду может бытьглобальная среда, или другиефункциональная среда(например, функция, которая содержит другую функцию).
Идите вперед и реализуйте это в псевдокоде:
GlobalExectionContext = { // 全局执行上下文
LexicalEnvironment: { // 词法环境
EnvironmentRecord: { // 环境记录
Type: "Object" // 全局环境
// 标识符绑定在这里
},
outer: <null> // 外部环境引用
}
}
FunctionExectionContext = { // 函数执行上下文
LexicalEnvironment: { // 词法环境
EnvironmentRecord: { // 环境记录
Type: "Object", // 函数环境
// 标识符绑定在这里
},
outer: < Global or FunctionEnvironment> // 外部环境引用
}
}
переменная среда
переменная средаПо сути, это еще и лексическая среда, поэтому она обладает всеми определенными выше свойствами лексической среды.
В ES6,Лексическийокружающая среда иПеременнаяСреда отличается тем, что первая используется для хранения объявлений функций и переменных (let
а такжеconst
)привязка, которая используется только для храненияПеременная(var
)** обязательная.
Кейс 🌰:
var a;
var b = 1;
let c = 2;
const d = 3;
function fn (e, f) {
var g = 4;
return e + f + g;
}
a = fn(10, 20);
Контекст выполнения выглядит следующим образом:
GlobalExectionContext = { // 全局执行上下文
ThisBinding: <Global Object>,
LexicalEnvironment: { // 词法环境
EnvironmentRecord: { // 环境记录
Type: "Object", // 全局环境
c: < uninitialized >,
d: < uninitialized >,
fn: < func >
},
outer: <null> // 外部环境引用
},
VariableEnvironment: { // 变量环境
EnvironmentRecord: { // 环境记录
Type: "Object",
a: < uninitialized >,
b: < uninitialized >
},
outer: <null>
}
}
FunctionExectionContext = { // 函数执行上下文
ThisBinding: <Global Object>, // this绑定window, 因为调用fn的是window对象
LexicalEnvironment: { // 词法环境
EnvironmentRecord: { // 环境记录
Type: "Object", // 函数环境
Arguments: { 0: 10, 1: 20, length: 2 }
},
outer: < GlobalLexicalEnvironment > // 全局环境的引用
},
VariableEnvironment: { // 变量环境
EnvironmentRecord: { // 环境记录
Type: "Object",
g: < uninitialized >
},
outer: < GlobalLexicalEnvironment > // 全局环境的引用
}
}
Итак, мы можем знатьпеременное продвижениеПричина в следующем:
На этапе создания объявления функций сохраняются в среде, а переменные устанавливаются в
undefined
(существуетvar
случае) или оставаться неинициализированным (вlet
а такжеconst
на случай, если). Вот почему можно получить доступ до объявленияvar
определенная переменная (хотя онаundefined
), но при доступе до объявленияlet
а такжеconst
Определенная переменная подскажет причину ошибки ссылки. Это называется переменным подъемом.
этап выполнения
Фаза выполнения в основном делает три вещи:
- присвоение переменной
- ссылка на функцию
- выполнить другой код
Примечание⚠️
Если механизм Javascript не может найти фактическое местоположение, указанное в исходном коде
var
значение переменной, то ей будет присвоеноundefined
стоимость.
фаза разрушения
После завершения выполнения он выталкивается из стека и ожидает уничтожения рециркуляции.
послесловие
Эта статья только оконтекст выполненияСделайте вводное введение уровня, и мы рассмотрим его более подробно позже.
Справочная статья:
Расширенный интерфейс Muyiyang — понимание контекста выполнения и стека выполнения в JavaScript