Научитесь лучше кодировать с более четким пониманием подъема JS

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

Совет. Превратите повторно используемый код JS в общие компоненты с помощью Bit (GitHub). Bit помогает каждому создавать модульные приложения JavaScript , легко обменивайтесь компонентами между проектами и командой и создавайте лучше и быстрее



Понимание того, что такое JavaScript Hoisting

Объявление и инициализация переменной происходят в следующей последовательности:

Декларация - ›Инициализация / Назначение -› Использование

// Variable lifecycle
let x;                 // Declaration
x = “hoisting”;        // Assignment
console.log(x);        // Usage

Однако, поскольку JavaScript разрешает как объявление, так и инициализацию переменных одновременно, это наиболее часто используемый шаблон:

let x = “hoisting”;

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

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

// hoisting
function Hoisting(){
  x = 100;
  let y = 200;
}
Hoisting();
console.log(x); // 100
console.log(y); // Reference Error: y is not defined

В приведенном выше примере кода есть функция Hoisting (). Таким образом, у нас есть переменная, которую мы не объявляли с помощью let / var / const, и переменная let y. Присвоение необъявленной переменной глобальной области видимости выполняется с помощью JavaScript. Но для переменной y мы получаем ReferenceError.

Хостинг в ES5

В ES5 мы учитываем ключевое слово var. Подъем с помощью var несколько отличается от let / const. Пример с var, чтобы увидеть, как работает подъем:

var num (global)
console.log(car);    // undefined
var car = ‘Lamborgini’;

В приведенном выше коде при регистрации имени переменной, которое было объявлено и присвоено позже, чем использовалось, компилятор выдает результат «неопределенный». Этого не ожидалось, так как мы должны были получить ReferenceError при попытке использовать переменную car еще до ее объявления.

Но интерпретатор видит это иначе, а именно:

//how interpreter sees the above code
var car;
console.log(car); // undefined
car = ‘Lamborgini’;

Хостинг в переменной области действия

Давайте узнаем, как происходит подъем переменных с функциональной областью видимости, на следующем примере:

//function scoped
function myFunc(){
  console.log(car);
  var car = ‘Lamborgini’;
}
myFunc();                // undefined

Однако нет никакой разницы по сравнению с кодом, в котором происходит объявление глобальной переменной. Интерпретатор выдает результат как «undefined».

//function scoped
function myFunc(){
 var car;
 console.log(car);
 car = ‘Lamborgoni’;
}
myFunc();                // undefined

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

function myFunc(){
  var car = ‘Lamborgini’;
  console.log(car)         // Lamborgini
}  
myFunc();

Подъем в ES6

Мы можем увидеть пример ниже:

let num(global)
console.log(num);
let num = 003;         // ReferencError: num is not defined

В ключевом слове var мы ожидаем, что вывод журнала будет неопределенным. Однако, поскольку let в es6 не разрешает использование необъявленных переменных, интерпретатор явно выдает ошибку ссылки. Это гарантирует, что мы всегда сначала объявляем нашу переменную.

Ключевые слова let и const.

Переменные и константы, объявленные с помощью let или const, не поднимаются!

Инициализации JavaScript не поднимаются

JavaScript поднимает только объявления, но не инициализации.

var a = “volkswagon”; // Initialize a
var b = “Lamborgini”; // Initialize b
elem = document.getElementById("car"); // Find an element
elem.innerHTML = a + " " + b;       // Display a and b as volkswagon and lamborgini

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

var a = “i10”;  // Initialize a
elem = document.getElementById("car");      // Find an element
elem.innerHTML = "a is " + a + “ and b is " + b;  // Display a and b
var b = “Lamborgini”;  // Initialize b
Result:
a is i10 and b is undefined

Следовательно, это происходит потому, что происходит только подъем объявления (var b), а не инициализация (= «Lamborgini») наверх. Из-за подъема b был объявлен до его использования, но поскольку инициализации не поднимаются, значение b не определено.

Подъемные классы

Классы JavaScript можно разделить на два класса:

  • Объявления классов
  • Выражения класса

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

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

var car1 = new car();
car1.height = 5;
car1.weight = 500;
console.log(car1);   // Output: ReferenceError: car is not defined
class car{
  constructor(height, weight) {
    this.height = height;
    this.weight = weight;
  }
}

В приведенном выше коде возникает ошибка ссылки. Это связано с тем, что после инициализации переменной car1 происходит определение класса car. Чтобы решить эту ошибку, нам просто нужно определить класс car перед инициализацией car1. Это хостинг в объявлении класса.

class car{
  constructor(height, weight) {
    this.height = height;
    this.weight = weight;
  }
}
var car1 = new car();
car1.height = 5;
car1.weight = 500;
console.log(car1);

Следовательно, это дает правильный результат.

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

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

Поэтому ниже приведен пример безымянного или анонимного варианта выражения класса:

var rect = new shapes();
rect.height = 10;
rect.width = 20;
console.log(rect); // Output: TypeError: shapes is not a constructor
var shapes = class {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
};

Таким образом, правильный способ сделать это так:

var shapes = class {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
};
var rect = new shapes();
rect.height = 10;
rect.width = 20;
console.log(rect);

Резюме

Для многих разработчиков Hoisting - это неизвестное поведение JavaScript. Многие разработчики также упускают из виду его важность. Более того, если разработчик не понимает подъема, программы могут содержать ошибки (ошибки). Во избежание ошибок всегда объявляйте все переменные в начале каждой области. Таким образом, именно так JavaScript интерпретирует код, это всегда хорошее правило.

Учить больше