Поднятие переменных и объявлений функций в JavaScript

В этом руководстве вы узнаете о поднятии переменных и объявлений функций в JavaScript и о том, как это работает внутри.

Когда механизм JavaScript выполняет код JavaScript, он создает глобальный контекст выполнения. Глобальный контекст выполнения состоит из двух фаз: создание и выполнение.

На этапе создания механизм JavaScript перемещает объявления переменных и функций в начало кода. Эта функция известна как поднятие или подъем в JavaScript.

Подъем переменных

Подъем переменных означает, что движок JavaScript перемещает объявления переменных в начало скрипта. Например, в следующем примере объявляется переменная counter и инициализируется ее значение равным 1 :

console.log(counter); // undefined
var counter = 1;

В этом примере мы ссылаемся на переменную счетчика перед объявлением.

Однако первая строка кода не вызывает ошибки. Причина в том, что движок JavaScript перемещает объявление переменной в начало скрипта.

Технически код на этапе выполнения выглядит следующим образом:

var counter;

console.log(counter); // undefined
counter = 1;

На этапе создания глобального контекста выполнения механизм JavaScript помещает переменную counter в память и инициализирует ее значение равным undefined.

Ключевое слово let

Следующее объявляет переменную counter с помощью ключевого слова let :

console.log(counter);
let counter = 1;

JavaScript выдает следующую ошибку:

"ReferenceError: Cannot access 'counter' before initialization

Сообщение об ошибке объясняет, что переменная счетчика уже находится в куче памяти. Однако он не был инициализирован.

За кулисами движок JavaScript поднимает объявления переменных, в которых используется ключевое слово let. Однако он не инициализирует let.

Обратите внимание, что если вы обращаетесь к несуществующей переменной, JavaScript выдаст другую ошибку:

console.log(alien);
let counter = 1;

Вот ошибка:

"ReferenceError: alien is not defined

Подъем функций

Как и переменные, движок JavaScript также поднимает объявления функций. Это означает, что движок JavaScript также перемещает объявления функций в начало скрипта.

Например:

let x = 20,
  y = 10;

let result = add(x, y);
console.log(result);

function add(a, b) {
  return a + b;
}

В этом примере мы вызвали функцию add() перед ее определением. Приведенный выше код эквивалентен следующему:

function add(a, b){
    return a + b;
}

let x = 20,
    y = 10;

let result = add(x,y);
console.log(result);

На этапе создания контекста выполнения механизм JavaScript помещает объявление функции add() в динамическую память. Чтобы быть точным, механизм JavaScript создает объект типа Function и ссылку на функцию с именем add, которая ссылается на объект функции.

Функциональные выражения

В следующем примере add из обычной функции заменяется выражением функции:

let x = 20,
    y = 10;

let result = add(x,y);
console.log(result);

var add = function(x, y) {
return x + y;
}

Если вы выполните код, произойдет следующая ошибка:

"TypeError: add is not a function

На этапе создания глобального контекста выполнения механизм JavaScript создает переменную add в памяти и инициализирует ее значение равным undefined.

При выполнении следующего кода add не undefined, следовательно, это не функция:

let result = add(x,y);

Переменная add назначается анонимной функции только на этапе выполнения глобального контекста выполнения.

Стрелочные функции

В следующем примере выражение add функции заменяется функцией стрелки:

let x = 20,
    y = 10;

let result = add(x,y);
console.log(result);

var add = (x, y) => x + y;

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

"TypeError: add is not a function

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

Заключение

  • Поднятие в JavaScript происходит на этапе создания контекста выполнения, который перемещает объявления переменных и функций в начало сценария.
  • Движок JavaScript поднимает переменные, объявленные с помощью ключевого слова let, но не инициализирует их как переменные, объявленные с помощью ключевого слова var.
  • Движок JavaScript не поднимает функциональные выражения и стрелочные функции.
Рейтинг
( Пока оценок нет )
Александр Русаков / автор статьи
Программист, разработчик, 12 лет опыта работы в крупных компаниях. Быстро освоил typescript, делюсь своими знаниями на страницах этого сайта.
Загрузка ...
JavaScript и TypeScript