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

Однако, напротив, необъявленные переменные не существуют до тех пор, пока не будет выполнен код, присваивающий им значение. Следовательно, присвоение значения необъявленной переменной неявно создает ее как глобальную переменную при выполнении присваивания. Это означает, что все необъявленные переменные являются глобальными переменными.

function hoist() {
  a = 20;
  var b = 100;
}

console.log(a); // error a is not defined

hoist();

console.log(a); // 20   a becomes global variable
console.log(b); // error b is not defined (it is defined in hoist method scope not global)

Разница между var, let и const с точки зрения подъема

Поднимаются все типы var, let и const, но есть разница в значении по умолчанию, с которым они поднимаются, например, в var они поднимаются с неопределенным значением, но в случае let и const они не инициализируются никаким значением.

console.log(x); // undefined
var x = 10;

Это даст undefined, потому что поднимается только объявление, а не инициализация. Таким образом, это будет интерпретировано как:

var x;
console.log(x);
x = 10;

Такое же поведение var также находится в функциональной области.

function getName() {
  console.log(name);
  var name = "Max";
}

getName(); // undefined

Чтобы избежать этого, мы можем объявить и определить переменную перед ее использованием.

function getName() {
  var name = "Max";
  console.log(name);
}

getName(); // Max

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

console.log(age); // Output: ReferenceError: age is not defined ...
let age = 25;

Таким образом, движок привязывает значение к переменной, где оно фактически объявлено. Итак, если мы напишем такой код

let age;
console.log(age); // undefined
age = 25;

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

В случае конст. Подобно ключевому слову let, интерпретатор спасает нас, вместо того чтобы молча завершать работу с неопределенным значением, явно выдавая ошибку ссылки.

console.log(age); // Output: ReferenceError: age is not defined ...
const age = 25;

Мы должны объявить и определить переменную const вместе. мы не можем отдельно так что.

const age;  // Missing initializer in const declaration

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

Функция может быть разделена на 2 части с точки зрения подъема:

Объявление функции Выражение функции

Объявление функции

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

function print(var name) {
  console.log(name);
}

В случае объявления функции вся функция поднимается, например:

print("Alax");  // Alax

function print(var name) {
  console.log(name);
}

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

При этом функция присваивается новой переменной

let printFn = function(var name) {
  console.log(name);
}

В этом случае поднимается только переменная, а не вся функция

printFn();   //Output: "printFn: expression is not a function

let printFn = function(var name) {
  console.log(name);
}

printFn инициализируется с помощью undefined, это не функция, когда мы ее вызываем, поэтому мы получаем эту ошибку.

Порядок старшинства

Объявления функций имеют приоритет над объявлениями переменных. Назначение переменных имеет приоритет над объявлениями функций.

var name = "Tom";

function name() {
  console.log("Harry");
}

console.log(typeof name); // string (variable assignment take precedence)
// 2nd Example
var name;

function name() {
  console.log("Harry");
}

console.log(typeof name); // function (function declaration take precedence)

Классы подъема

Подъем классов аналогичен подъему функций. Он также имеет 2 вида

Объявления классов

Выражения класса

Объявления классов

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

var name = fullName();
name.firstName = "Sourav";
name.lastName = "Ganguly";
console.log(name); // Reference error!!!

class fullName {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
}

Поэтому мы должны объявить и определить класс поверх кода, где мы его используем.

class fullName {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
}

var name = fullName();
name.firstName = "Sourav";
name.lastName = "Ganguly";
console.log(name); // Output {firstName: "Sourav", lastName: "Ganguly"}

КлассВыражение

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

var name = getFullName();
name.firstName = "Sourav";
name.lastName = "Ganguly";
console.log(name); // TypeError!!! getFullName is not a constructor

var getFullName = class fullName {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
};