Что такое «контекст выполнения» в JavaScript? - PullRequest
57 голосов
/ 22 февраля 2012

Мой заголовок в значительной степени суммирует все это.

Может кто-нибудь просветить меня о ...

«Что такое« контекст выполнения »в JavaScript?»

и как это связано с «этим», подъемом, цепочкой прототипов, областью видимости и сборкой мусора?

Ответы [ 8 ]

50 голосов
/ 22 февраля 2012

Вы спрашиваете о нескольких разных концепциях, которые не очень тесно связаны.Я постараюсь кратко остановиться на каждом из них.


Контекст выполнения - это концепция в спецификации языка, которая, с точки зрения непрофессионала, примерно соответствует «среде», в которой выполняется функция;то есть область видимости переменных (и цепочка областей видимости , переменные в замыканиях из внешних областей), аргументы функций и значение объекта this.

стек вызовов представляет собой набор контекстов выполнения.

См. Также этот ответ и эту статью .


Scope буквально означает: область, в которой можно получить доступ к переменной.Упрощенно:

var x;

function a() {
    var y;
}

x можно получить доступ из любого места.Когда вызывается a, x будет во внешней области видимости.(Хранится в цепочке областей действия .)

Напротив, y может быть доступен только с помощью кода в a(), поскольку он ограничен областью действия a.Вот что делает ключевое слово var: ограничивает переменную локальной областью действия.Если мы пропустим var, y окажется в глобальной области действия , что обычно считается плохой вещью.


Представьте себе подъем как болеевещи во время компиляции.В JavaScript объявления функций «подняты» наверх.Другими словами, они анализируются и оцениваются перед любым другим кодом.(Это в отличие от функции выражений , которые оцениваются внутри строки.) Обратите внимание на следующее:

a();
b();

function a() { }
var b = function() { }

Вызов a() будет успешным, поскольку его объявление поднято наверх;a был назначен автоматически до начала выполнения программы.Вызов b() завершится неудачно с TypeError, потому что b не будет определено до строки 4.

8 голосов
/ 25 июня 2017

Вы задали так много понятий, но давайте выберем одно за другим и поймем их.

Среда, в которой работает ваш код: Execution context. Он создается при выполнении вашего кода.

Execution Context (Global), созданный JS Engine, содержит 3 важные вещи для вас:

  1. Глобальный объект - window
  2. Специальный объект this
  3. Ссылка на внешнюю среду

Давайте рассмотрим простой пример, чтобы понять Global Execution Context:

var a = "Hello World";

function b(){

}

Когда JS Engine запускает приведенный выше код, он создает следующий контекст выполнения (показан на рисунке): Глобальный контекст выполнения


Теперь давайте посмотрим, как JS Engine создает Execution Context (тогда мы выкопаем и поймем подъем): рассмотрим этот сценарий:

b();
console.log(a);

var a = "Hello World!";
function b(){
    console.log("Called b!");
}

Я могу вызвать функцию b(), даже если она будет объявлена ​​позже. Это означает, что JS Engine делает что-то перед выполнением моего кода, давайте посмотрим, что:

JS Engine выполняет следующие два шага при выполнении любого кода:

ФАЗА СОЗДАНИЯ :

  • Разбор JS Engine - прогнать ваш код & identifies variables & functions, созданный кодом (который будет использоваться на этапе выполнения)
  • Установка пространства памяти для переменных и функций - «Подъем»
  • Подъем - перед выполнением кода JS Engine выделяет пространство памяти для Var & Func, используемого внутри кода. Эти переменные и функции составляют контекст выполнения любой функции, которая должна быть выполнена. Все переменные в JS изначально имеют значение undefined.

ФАЗА исполнения: довольно просто понять,

  • Когда код выполняется построчно (интерпретатором JS), он может получить доступ к переменным, определенным в контексте выполнения
  • присваивание переменной выполняется на этом этапе

Новый контекст выполнения создается при каждом вызове функции

Стек контекста выполнения: Что происходит, когда вы вызываете функцию:

function b(){

}

function a(){
    b();
}

a();
  • Теперь, прежде всего, будет создано Global Execution Context (как объяснено выше)

  • затем запускается выполнение и встречает переводчик call to function a(), и here a new execution context is created pushed on top EC Stack

    , поэтому каждый раз, когда вы вызываете функцию, новый EC создается и помещается поверх стека EC.

  • так что теперь EC for a() is CREATED interpreeter выполнит код внутри a() построчно

  • затем intrepreeter встречает call to function b(), это создает другой EC, который помещается сверху или EC стек

  • Когда b() завершится, он будет вытолкнут из стека, тогда a() закончится и вплоть до Global EC

см. Стек выполнения для приведенного выше фрагмента кода

3 голосов
/ 24 мая 2017

Я затронул только темы, которые наиболее тесно связаны.

Контекст выполнения - это оболочка вокруг существующего кода;который содержит код , который вы не написали ;но генерируется JS Engine.

Он состоит из следующих элементов:

  1. Глобальный объект
  2. 'this'
  3. Внешняя среда
  4. Ваш код

Контекст выполнения создается каждый раз, когда вы запускаете файл / приложение .js.Первый шаг на этом этапе создания - Подъем .JS Engine резервирует пространство или памяти настроек для всех переменных и функций, определенных в вашем коде.Затем они доступны, когда ваш код выполняется построчно.

Например:

b();
console.log(a);
var a = "hi!";
function b() {
    console.log("calling function");
}

Здесь переменные b () и a доступны до того, как они будут определены, однако,из-за подъема консоль не выдаст никакой ошибки.

Вывод будет выглядеть так - (попробуйте)

calling function
undefined

Обратите внимание, как функция была выполнена полностью, но у нас есть undefined для переменной.Это потому, что Подъем выполняется по-разному для функций и переменных.Функция целиком заносится в память, но для переменных пространство резервируется как заполнитель со значением undefined .Фактическое значение затем заменяется, когда двигатель последовательно выполняет ваш код.

Надеюсь, это прояснит для вас концепцию.

0 голосов
/ 09 июня 2019

Когда вы выполняете функцию, вы создаете новую execution context, содержащую локальную память, которая называется variable environment и this, которая является заполнителем, она будет ссылаться в контексте выполнения на все, что осталось от . где эта функция вызывается.

0 голосов
/ 24 мая 2018

Я хотел бы обратиться к

  1. Контекст
  2. этот контекст (связь с контекстом)
  3. Область

1: контекст выполнения

JavaScript - это однопоточный язык, то есть одновременно может выполняться только одна задача. Когда интерпретатор JavaScript первоначально выполняет код, он сначала входит в глобальный контекст выполнения по умолчанию . Каждый вызов функции с этого момента приведет к созданию нового контекста выполнения.

Здесь часто возникает путаница, термин контекст выполнения фактически означает все намерения и цели, относящиеся скорее к сфере, а не к контексту. Это неудачное соглашение об именах, однако это терминология, определенная спецификацией ECMAScript, поэтому мы как-то застряли с ней.

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

Контекст выполнения можно разделить на этап создания и выполнения. На этапе создания интерпретатор сначала создает переменный объект (также называемый объектом активации), который состоит из всех переменных, объявлений функций и аргументов, определенных в контексте выполнения. Оттуда цепочка областей действия инициализируется следующим, и значение этого определяется последним. Затем на этапе выполнения код интерпретируется и выполняется.

2: этот контекст

Что такое «этот» контекст? Контекст чаще всего определяется тем, как вызывается функция. Когда функция вызывается как метод объекта, это устанавливается для объекта, для которого вызывается метод:

var obj = {
    foo: function() {
        return this;   
    }
};

obj.foo() === obj; // true

Тот же принцип применяется при вызове функции с оператором new для создания экземпляра объекта. Когда вызывается таким образом, значение этого в рамках функции будет установлено на вновь созданный экземпляр:

function foo() {
    alert(this);
}

foo() // window
new foo() // foo

При вызове в качестве несвязанной функции по умолчанию используется глобальный контекст или объект окна в браузере. Однако, если функция выполняется в строгом режиме, контекст по умолчанию будет неопределенным.

3: переменная область действия

Переменная может быть определена либо в локальной, либо в глобальной области действия , которая устанавливает доступность переменных из разных областей во время выполнения. Любая определенная глобальная переменная, означающая, что любая переменная, объявленная вне тела функции, будет жить во время выполнения и может быть доступна и изменена в любой области видимости. Локальные переменные существуют только в теле функции, для которого они определены, и будут иметь различную область видимости для каждого вызова этой функции. Там он подлежит присваиванию значений, извлечению и манипулированию только внутри этого вызова и недоступен за пределами этой области.

ECMAScript 6 (ES6 / ES2015) ввел ключевые слова let и const , которые поддерживают объявление локальных переменных области блока. Это означает, что переменная будет ограничена областью действия блока, в котором она определена, например оператором if или циклом for, и не будет доступна вне открывающих и закрывающих фигурных скобок блока. Это противоречит объявлениям var, которые доступны вне блоков, в которых они определены. Разница между let и const заключается в том, что объявление const, как следует из названия, является константой - ссылка только для чтения на значение. Это не означает, что значение является неизменным, просто идентификатор переменной не может быть переназначен .

Для других тем: GC: * ​​1057 * GC Прототипирование: Прототипирование

0 голосов
/ 01 июля 2017

«Контекст выполнения» - это зонтик, который оборачивает весь код, помогая управлять им. Это как менеджер, который управляет любой средой. Поскольку существует очень много лексических сред, потому что в приложении JavaScript у вас много переменных и функций, вам нужен способ управлять всем. Что идет первым, что идет вторым и так далее, и если у вас не было среды «контекста выполнения», все идет к черту. Поэтому рассмотрите «Контекст выполнения» как обертку, управляющую вашим кодом.

0 голосов
/ 02 июля 2016

Контекст выполнения - это оболочка, помогающая управлять кодом, который выполняется В вашем коде вы увидите, что множество лексических сред означает, что области кода между {}, но текущая из которых управляется, управляются с помощью contextx выполнения. Она может содержать ваш код, а также может содержать то, что вы написали в своем коде.

0 голосов
/ 22 февраля 2012

Полагаю, простой пример объяснит все.

Примечание: function.call(object) вызывает функцию function в контексте object

// HTML

​<p id="p"></p>​​​​​​​​​​​​​​​​​​​​​​​​

// JavaScript

function helloWorld() {
    alert("HelloWorld: " + this);
}

var p = document.getElementById("p");
helloWorld();                // HelloWorld: [object DOMWindow]
helloWorld.call(window);     // HelloWorld: [object DOMWindow]
​​​​​​helloWorld.call("String");   // HelloWorld: String // Note: "toString()"
helloWorld.call​​​​(p);          // HelloWorld: [object HTMLParagraphElement]
helloWorld.call(new Date());​​​​ // HelloWorld: Tue Feb 21 2012 21:45:17 GMT+0100 (Central Europe Standard Time)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...