Временная мертвая зона

Если вы используете новые функции es6, вы могли столкнуться с причудой, связанной с let. Но прежде чем я расскажу о позвольте, позвольте (без каламбура) мне сделать небольшой крюк, чтобы var приземлиться. В JavaScript, когда вы объявляете переменную, эта переменная поднимается вверх вашего кода. Это означает, что вы можете получить доступ к переменной в коде, который идет до объявления.

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

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

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

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

Теперь вернемся к делу. let позволяет использовать область видимости на уровне блоков в JavaScript. Ознакомиться с ним можно здесь. Если вы запустите тот же фрагмент выше с заменой var на let, это произойдет.

}
  console.log(x); // ReferenceError!
  let x = 2;
}

Это происходит, когда вы пытаетесь получить доступ к объявленной переменной let раньше. Причина в том, что объявленные переменные let находятся во временной мертвой зоне (TDZ).

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

console.log(a); // undefined
var a;
console.log(b); // ReferenceError!
let b;

Разница в том, что вы не можете получить доступ к объявленной переменной let до тех пор, пока не произойдет инициализация и ей не будет присвоено значение (неявно или явно). Этого не произойдет, пока это заявление:

 let b;

или это

let b = 'some value';

запущен.

let b = 'hello';
console.log(b); // hello
let c;
console.log(c); // undefined

Вот и все. Надеюсь, это устранит все проблемы с TDZ, возникающие при использовании let.