- Оригинальный адрес:Understanding Execution Context and Execution Stack in Javascript
- Оригинальный автор:Sukhjinder Arora
- Перевод с:Программа перевода самородков
- Постоянная ссылка на эту статью:GitHub.com/rare earth/gold-no…
- Переводчик:CoolRice
- Корректор:linxuesia, CoderMing
фото черезUnsplashавторGreg Rakozy
Если вы или хотите стать разработчиком JavaScript, вы должны знать, как выполняется программа JavaScript. Понимание контекста реализации и действующего стека имеет решающее значение для понимания других концепций JavaScript, таких как объявления переменных, области видимости и замыкания.
Правильное понимание концепций контекста выполнения и стека выполнения сделает вас лучшим разработчиком JavaScript.
Без лишних слов, приступим :)
поделился сBitблог ❤️
Используя компоненты, предоставляемые приложением Bit, в качестве строительных блоков, вы являетесь архитектором. Делитесь, открывайте и разрабатывайте компоненты со своей командой в любое время и в любом месте, приходите и попробуйте!
Что такое контекст выполнения?
Проще говоря, контекст выполнения — это абстракция среды, в которой оценивается и выполняется код JavaScript. Всякий раз, когда код Javascript выполняется, он выполняется в контексте выполнения.
тип контекста выполнения
В JavaScript существует три типа контекста выполнения.
-
глобальный контекст выполнения— Это контекст по умолчанию или базовый, любой код не внутри функции находится в глобальном контексте. Он делает две вещи: создает глобальный объект окна (в случае браузера) и устанавливает
this
Значение равно этому глобальному объекту. В программе существует только один глобальный контекст выполнения. - контекст выполнения функции— Всякий раз, когда вызывается функция, для этой функции создается новый контекст. Каждая функция имеет свой собственный контекст выполнения, но создается при вызове функции. Контекстов функций может быть любое количество. Всякий раз, когда создается новый контекст выполнения, он выполняет серию шагов в определенном порядке (обсуждается позже).
-
Контекст выполнения функции Eval- выполнить на
eval
Код внутри функции также будет иметь свой контекст выполнения, но поскольку разработчики JavaScript не часто используютeval
, так что я не буду обсуждать это здесь.
стек выполнения
Стек выполнения, также известный как «стек вызовов» в других языках программирования, представляет собой стек со структурой данных LIFO (последний вошел, первый вышел), которая используется для хранения всех контекстов выполнения, созданных при выполнении кода.
Когда движок JavaScript впервые встречает ваш сценарий, он создает глобальный контекст выполнения и помещает его в текущий стек выполнения. Всякий раз, когда механизм встречает вызов функции, он создает новый контекст выполнения для этой функции и помещает его на вершину стека.
Механизм выполняет функции, контекст выполнения которых находится на вершине стека. Когда выполнение функции завершается, контекст выполнения извлекается из стека, и поток управления переходит к следующему контексту в текущем стеке.
Давайте разберемся со следующим примером кода:
let a = 'Hello World!';
function first() {
console.log('Inside first function');
second();
console.log('Again inside first function');
}
function second() {
console.log('Inside second function');
}
first();
console.log('Inside Global Execution Context');
Стек контекста выполнения приведенного выше кода.
Когда приведенный выше код загружается в браузер, механизм JavaScript создает глобальный контекст выполнения и помещает его в текущий стек выполнения. при встречеfirst()
Когда вызывается функция, механизм JavaScript создает новый контекст выполнения для функции и помещает его поверх текущего стека выполнения.
когда изfirst()
вызов внутри функцииsecond()
функция, движок JavaScriptsecond()
Функция создает новый контекст выполнения и помещает его поверх текущего стека выполнения. когдаsecond()
После выполнения функции ее контекст выполнения извлекается из текущего стека, и поток управления достигает следующего контекста выполнения, а именноfirst()
Контекст выполнения функции.
когдаfirst()
После выполнения его контекст выполнения извлекается из стека, и поток управления достигает глобального контекста выполнения. Как только весь код выполнен, механизм JavaScript удаляет глобальный контекст выполнения из текущего стека.
Как создать контекст выполнения?
Теперь, когда мы увидели, как JavaScript управляет контекстами выполнения, давайте разберемся, как движки JavaScript создают контексты выполнения.
Существует две фазы создания контекста выполнения:1) Этап созданияа также2) Фаза выполнения.
The Creation Phase
Перед выполнением кода JavaScript контекст выполнения проходит этап создания. На этапе создания происходят три вещи:
- thisценностное решение, известное какЭта привязка.
- СоздайтеЛексическое окружениекомпоненты.
- Создайтепеременная средакомпоненты.
Итак, контекст выполнения концептуально представлен следующим образом:
ExecutionContext = {
ThisBinding = <this value>,
LexicalEnvironment = { ... },
VariableEnvironment = { ... },
}
Эта привязка:
В глобальном контексте выполненияthis
Значение глобального объекта. (В браузере,this
ссылка на объект Window).
В контексте выполнения функцииthis
Значение зависит от того, как была вызвана функция. Если он вызывается ссылочным объектом, тоthis
будет установлен на этот объект, в противном случаеthis
Значение установлено на глобальный объект илиundefined
(в строгом режиме). Например:
let foo = {
baz: function() {
console.log(this);
}
}
foo.baz(); // 'this' 引用 'foo', 因为 'baz' 被
// 对象 'foo' 调用
let bar = foo.baz;
bar(); // 'this' 指向全局 window 对象,因为
// 没有指定引用对象
Лексическое окружение
Официальный ES6Документация определяет лексическую среду как
Лексическое окружениеэто канонический тип, определенный на основе лексически вложенной структуры кода ECMAScript.идентификаторассоциации с конкретными переменными и функциями. Лексическая среда состоит из регистратора среды и возможной ссылкивнешнийЛексическое окружение состоит из пустых значений.
Проще говоряЛексическое окружениеявляется холдингомотображение идентификатор-переменнаяСтруктура. (здесьидентификаторЭто относится к имени переменной/функции, иПеременнаяявляется ссылкой на фактический объект [содержащий объект функционального типа] или необработанные данные).
Теперь в лексическом окружениивнутреннийЕсть два компонента: (1)Регистратор окружающей средыи (2) ассылка на внешнюю среду.
- Регистратор окружающей средыэто фактическое место, где хранятся объявления переменных и функций.
- ссылка на внешнюю средуОзначает, что он имеет доступ к своему родительскому лексическому окружению (области действия).
Лексическое окружениеЕсть два типа:
-
глобальная среда(в глобальном контексте выполнения) — это лексическое окружение без ссылок на внешнее окружение. Ссылка внешней среды на глобальную средуnull. Он имеет встроенный объект/массив/и т. д., функции прототипа в регистраторе среды (связанные с глобальными объектами, такими как объект окна) и любые определяемые пользователем глобальные переменные, и
this
Значение указывает на глобальный объект. - существуетфункциональная среда, пользовательские переменные внутри функции хранятся вРегистратор окружающей средысередина. И внешней средой, на которую ссылаются, может быть глобальная среда или любая внешняя функция, содержащая эту внутреннюю функцию.
Регистратор окружающей средыЕсть также два типа (как указано выше!):
- Декларативный регистратор средыХраните переменные, функции и параметры.
- Рекордер объектной средыиспользуется для определения появления вглобальный контекстСвязь между переменными и функциями в .
вкратце,
- существуетглобальная среда, регистратор среды — это регистратор среды объекта.
- существуетфункциональная среда, регистратор среды является декларативным регистратором среды.
Уведомление -дляфункциональная среда,Декларативный регистратор средыТакже включает в себя проход к функцииarguments
объект (в этом объекте хранится карта индексов и параметров) и параметры, переданные в функциюlength.
Абстрактно говоря, лексическое окружение в псевдокоде выглядит так:
GlobalExectionContext = {
LexicalEnvironment: {
EnvironmentRecord: {
Type: "Object",
// 在这里绑定标识符
}
outer: <null>
}
}
FunctionExectionContext = {
LexicalEnvironment: {
EnvironmentRecord: {
Type: "Declarative",
// 在这里绑定标识符
}
outer: <Global or outer function environment reference>
}
}
Переменная среда:
Это также лексическая среда, регистратор среды которой содержитоператор объявления переменнойПривязки, созданные в контексте выполнения.
Как упоминалось выше, переменное окружение также является лексическим окружением, поэтому оно обладает всеми свойствами лексического окружения, определенными выше.
В ES6,Лексическое окружениекомпоненты ипеременная средаОдно значение состоит в том, что первый используется для хранения деклараций функций и переменных (let
а такжеconst
) привязка, в то время как последняя используется только для храненияvar
привязка переменных.
Давайте взглянем на пример кода, чтобы понять вышеприведенные концепции:
let a = 20;
const b = 30;
var c;
function multiply(e, f) {
var g = 20;
return e * f * g;
}
c = multiply(20, 30);
Контекст выполнения выглядит так:
GlobalExectionContext = {
ThisBinding: <Global Object>,
LexicalEnvironment: {
EnvironmentRecord: {
Type: "Object",
// 在这里绑定标识符
a: < uninitialized >,
b: < uninitialized >,
multiply: < func >
}
outer: <null>
},
VariableEnvironment: {
EnvironmentRecord: {
Type: "Object",
// 在这里绑定标识符
c: undefined,
}
outer: <null>
}
}
FunctionExectionContext = {
ThisBinding: <Global Object>,
LexicalEnvironment: {
EnvironmentRecord: {
Type: "Declarative",
// 在这里绑定标识符
Arguments: {0: 20, 1: 30, length: 2},
},
outer: <GlobalLexicalEnvironment>
},
VariableEnvironment: {
EnvironmentRecord: {
Type: "Declarative",
// 在这里绑定标识符
g: undefined
},
outer: <GlobalLexicalEnvironment>
}
}
Уведомление— только когда встречается вызывающая функцияmultiply
, будет создан контекст выполнения функции.
может быть, вы заметилиlet
а такжеconst
Определенная переменная не имеет никакого связанного с ней значения, ноvar
Определенная переменная устанавливается вundefined
.
Это связано с тем, что на этапе создания движок проверяет код, чтобы найти объявления переменных и функций, и хотя объявления функций полностью хранятся в среде, переменные изначально устанавливаются вundefined
(var
case) или неинициализированные (let
а такжеconst
кейс).
Вот почему вы можете получить доступ до объявленияvar
определенная переменная (хотя этоundefined
), Но доступ до Декларацииlet
а такжеconst
Переменная получит ошибку ссылки.
Это то, что мы называем подъемом объявлений переменных.
этап выполнения
Это самая легкая часть всей статьи. На этом этапе выполняется присвоение всех этих переменных, и, наконец, выполняется код.
Уведомление— На этапе выполнения, если движок JavaScript не может быть найден в фактическом месте, указанном в исходном коде.let
значение переменной, оно будет присвоено какundefined
.
В заключение
Мы уже обсуждали, как программы JavaScript выполняются внутри. Хотя вам не нужно изучать все эти концепции, чтобы быть хорошим разработчиком JavaScript, хорошее понимание вышеперечисленных концепций поможет вам легче и глубже понять другие концепции, такие как подъем объявления переменных, область видимости и замыкания.
Вот и все, если вы нашли эту статью полезной, нажмите кнопку 👏 и не стесняйтесь комментировать ниже! Хотел бы обсудить с вами 😃.
поделился сBitблог
Bit упрощает совместное использование небольших компонентов и модулей в проектах и приложениях, что позволяет вам и вашей команде быстрее создавать код. Делитесь, открывайте и разрабатывайте компоненты со своей командой в любое время и в любом месте, приходите и попробуйте!
понять больше
Если вы обнаружите ошибки в переводе или в других областях, требующих доработки, добро пожаловать наПрограмма перевода самородковВы также можете получить соответствующие бонусные баллы за доработку перевода и PR. начало статьиПостоянная ссылка на эту статьюЭто ссылка MarkDown этой статьи на GitHub.
Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из ИнтернетаНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,товар,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.