You are currently viewing JavaScript | Hoisting

JavaScript | Hoisting

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

Это позволяет нам вызывать функции, даже не записывая их в наш код.

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

JavaScript выделяет память для всех переменных и функций, определенных в программе перед выполнением.

Давайте разберемся, что именно это такое:
ниже приведена последовательность, в которой происходит объявление и инициализация переменной.

Объявление –> Инициализация/Назначение –>> Использование

// Variable lifecycle
let a; // Declaration
a = 100; // Assignment
console.log(a); // Usage

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

let a = 100;

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

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

// hoisting
function codeHoist(){
	a = 10;
	let b = 50;
}
codeHoist();

console.log(a); // 10
console.log(b); // ReferenceError : b is not defined

Выход:

Пояснение: В приведенном выше примере кода мы создали функцию с именем codeHoist (), и там у нас есть переменная, которую мы не объявляли, используя let/var/const и переменную a let b. Необъявленной переменной присваивается глобальная область javascript, поэтому мы можем распечатать ее вне функции, но в случае переменной b область ограничена, и она недоступна снаружи, и мы получаем ошибку ссылки.

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

ES5

Когда мы говорим об ES5, переменная, которая приходит нам в голову, — это var. Подъем с помощью var несколько отличается по сравнению с let/const. Давайте воспользуемся var и посмотрим, как работает подъем:

// var code (global)
console.log(name); // undefined
var name = 'Mukul Latiyan';

Выход:

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

Но интерпретатор видит это по-другому, приведенный выше код выглядит так:

//how interpreter sees the above code
var name;
console.log(name); // undefined
name = 'Mukul Latiyan';

Выход:

Переменная области действия

Давайте посмотрим, как поднимаются переменные области действия.

//function scoped
function fun(){
	console.log(name);
	var name = 'Mukul Latiyan';
}
fun(); // undefined

Выход:

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

//function scoped
function fun(){
	var name;
	console.log(name);
	name = 'Mukul Latiyan';
}
fun(); // undefined

Выход:

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

//in order to avoid it
function fun(){
	var name = 'Mukul Latiyan';
	console.log(name); // Mukul Latiyan
}
fun();

Выход:

ES6

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

Пример:

//let example(global)
console.log(name);
let name='Mukul Latiyan'; // ReferencError: name is not defined

Выход:

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

const ведет себя аналогично let, когда дело доходит до подъема.