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

Контексты выполнения создаются каждый раз, когда вы объявляете функцию. Каждый раз! У них также есть две фазы: фаза создания и фаза исполнения. Фаза создания — это когда ваша функция объявляется/записывается, а фаза выполнения — когда ваша функция вызывается/выполняется. Например, какое значение возвращает эта функция?

var name = 'Lindsey';
function sayHi(name) {
  return 'Hi ' + name + '!';
}

Ответ… ничего. Функция sayHi была создана, но никогда не выполнялась. Таким образом, у него еще нет возвращаемого значения. Следовательно, и это важно, функция действительно не имеет значения в вашем коде, пока она не будет вызвана. Теперь давайте посмотрим на этот пример… Какое значение возвращает этот код?

var name = 'Lindsey';
function sayHi(name) {
  return 'Hi ' + name + '!';
}
sayHi(name);                                //returns 'Hi Lindsey!

Возвращаемое значение соответствует ожидаемому: «Привет, Линдси!» Итак, как вы можете видеть, контекст выполнения состоит из двух фаз: когда вы объявляете функцию, как мы сделали здесь с sayHi, и когда вы выполняете функцию, как мы делали, когда вызывали sayHi(name). Это важный пример для понимания разницы между двумя фазами контекста выполнения. Но этот пример технически выполняется по порядку. Сначала мы присвоили переменную, затем мы объявили функцию с параметром, затем мы вызвали эту функцию, назначив нашу переменную этому параметру. Но что, если мы напишем немного более сложный код. Возьмем, к примеру, этот кусок. После того, как он запустится, в каком порядке вы ожидаете, что это журналы?

console.log('1');
function sayHi() {
  console.log('hi');
}
console.log('2');
sayHi();
console.log('3');

Сначала у нас есть журнал консоли, затем объявление функции, затем второй журнал консоли, затем вызов функции и, наконец, третий журнал консоли. Если вы думаете, что это 1, «привет», «2», 3, то вы думаете, что интерпретатор Javascript работает в том порядке, в котором все написано. Однако на самом деле ответ 1, 2, «привет», 3.

Причина этого в том, что функция sayHi была объявлена ​​до console.log(‘2’), но была вызвана после console.log(‘2’). Поскольку она была вызвана позже, она регистрируется после 2. Опять же, функция имеет значение только после того, как она была вызвана.

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