Недавний разговор с коллегамиРазличия между варми и буквами, меня дразнили за то, что я воспитываюvar имеет переменный подъем, а let — нет.мнение о. Разве это не самый часто задаваемый вопрос на собеседовании, на мой взгляд? Но после некоторых тщательных исследований я обнаружил, что все не так, как я себе представлял, т.е.Пусть также имеет переменное продвижение, но пусть имеет временную мертвую зону.
переменное продвижение
Докажите, что объявления var имеют подъем переменных
Обычно мы доказываем, что переменная var имеет подъем переменных вот так.
function fn(){
console.log(a) // undefined
var a = 12
}
fn()
Почему этот код выводит undefined вместо сообщения об ошибке?
Причина в том, что когда js создает контекст выполнения, он проверяет код, находит объявления переменных и объявления функций и полностью сохраняет объявления функций в окружении, а переменные, объявленные через var, устанавливает в значение undefined, что называется продвижением переменных. Буквально объявления переменных и функций перемещаются в начало функции или глобального кода.
Так что же произойдет, если мы заменим var на let?
function fn(){
console.log(a) // Uncaught ReferenceError: a is not defined
let a = 12
}
fn()
Как и ожидалось, код сообщил об ошибке. Многие думают, что в этом контрпримере у let нет продвижения переменных, но на самом деле это не так. Приведенный выше пример может только доказать, что var имеет переменное продвижение, но не доказывает, что let не имеет переменного продвижения.
Докажите подъем переменной в объявлении let
Возьмем другой пример:
var x = 'parent value';
(function() {
console.log(x); // parent value
}())
Код выведет родительское значение, причина очень проста, она включает в себяцепочка прицеловзнание. Если переменная x не найдена в области анонимной функции, она будет следовать цепочке областей, чтобы найти родительскую область, а затем найти переменную x в родительской области и вывести ее.
Затем добавляем let для объявления переменных в анонимной функции, что получится в результате?
var x = 'parent value';
(function() {
console.log(x); // Uncaught ReferenceError: x is not defined
let x = 'child value'
}())
Не могу думать об этом! В это время код снова сообщит об ошибке Отсюда видно, что let тоже существует.переменное продвижениеДа, знания не могут читать или записывать переменную до того, как переменная будет явно назначена, иначе будет сообщено об ошибке, что является так называемым let и constВременная мертвая зона.
Цитирование определения на MDN
Привязки let создаются в верхней части области (блока), содержащей объявление, обычно называемое «подъемом».В отличие от переменных, объявленных с помощью var, которые начинаются со значения undefined, переменные let не инициализируются до тех пор, пока не будет оценено их определение. Обращение к переменной перед инициализацией приводит к ошибке ReferenceError, Переменная находится во «временной мертвой зоне» с начала блока до обработки инициализации.
Вероятно, это означает, что у let также есть подъем переменных, но форма отличается от формы var.Переменным, определенным с помощью var, будет присвоено начальное значение undefined, в то время как let не будет присвоено начальное значение до того, как оно будет явно назначено, и это не будет присвоено начальное значение.Ранее чтение и запись переменных вызывали сообщение об ошибке ReferenceError. Область от начала кодового блока (блока) до оценки переменной (включая присваивание) называется временной мертвой зоной переменной.
var x = 'parent value';
(function() {
// let x 此时暂时性死区开始
console.log(x); // Uncaught ReferenceError: x is not defined
//暂时性死区结束
let x = 'child value'
}())
Суммировать
Оказывается, у let и var тоже есть подъем переменных, а в объявлении let тоже есть понятие временной мертвой зоны.