Разница заключается в области переменных, объявленных для каждой из них.
На практике разница в масштабах имеет ряд полезных последствий:
let
переменные видны только в их ближайшем охватывающем блоке ({ ... }
).
let
переменные можно использовать только в строках кода, которые появляются после объявления переменной (даже если они подняты!).
let
переменные не могут быть повторно объявлены последующими var
или let
.
- Глобальные
let
переменные не добавляются к глобальному объекту window
.
let
переменные просты в использовании с замыканиями (они не вызывают состояния гонки < / а>).
Ограничения, накладываемые let
, уменьшают видимость переменных и увеличивают вероятность того, что неожиданные конфликты имен будут обнаружены раньше. Это упрощает отслеживание и анализ переменных, включая их достижимость (помогает освободить неиспользуемую память) .
Следовательно, let
переменные с меньшей вероятностью будут вызывать проблемы при использовании в больших программах или когда независимо разработанные фреймворки комбинируются новыми и неожиданными способами.
var
может быть полезен, если вы уверены, что хотите получить эффект однократной привязки при использовании замыкания в цикле (# 5) или для объявления видимых извне глобальных переменных в вашем коде (# 4). Использование var
для экспорта может быть отменено, если _14 _ мигрирует из пространства транспилятора на базовый язык.
Примеры
1. Не использовать за пределами ближайшего включающего блока: этот блок кода вызовет ошибку ссылки, потому что второе использование x
происходит за пределами блока, в котором он объявлен с let
:
{
let x = 1;
}
console.log(`x is ${x}`); // ReferenceError during parsing: "x is not defined".
Напротив, тот же пример с var
работает.
2. Бесполезно перед объявлением:
Этот блок кода выдаст ReferenceError
перед запуском кода, потому что x
используется перед объявлением:
{
x = x + 1; // ReferenceError during parsing: "x is not defined".
let x;
console.log(`x is ${x}`); // Never runs.
}
Напротив, тот же пример с var
анализирует и запускается без каких-либо исключений.
3. Без повторного объявления: Следующий код демонстрирует, что переменная, объявленная с помощью let
, не может быть повторно объявлена позже:
let x = 1;
let x = 2; // SyntaxError: Identifier 'x' has already been declared
4. Глобальные объекты, не прикрепленные к window
:
var button = "I cause accidents because my name is too common.";
let link = "Though my name is common, I am harder to access from other JS files.";
console.log(link); // OK
console.log(window.link); // undefined (GOOD!)
console.log(window.button); // OK
5. Простое использование с замыканиями. Переменные, объявленные с помощью var
, не работают с замыканиями внутри циклов. Вот простой цикл, который выводит последовательность значений, которые переменная i
имеет в разные моменты времени:
for (let i = 0; i < 5; i++) {
console.log(`i is ${i}`), 125/*ms*/);
}
В частности, это выводит:
i is 0
i is 1
i is 2
i is 3
i is 4
В JavaScript мы часто используем переменные значительно позже, чем когда они были созданы. Когда мы демонстрируем это, задерживая вывод с закрытием, переданным в setTimeout
:
for (let i = 0; i < 5; i++) {
setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
}
... вывод остается неизменным, пока мы придерживаемся let
. Напротив, если бы мы использовали вместо этого var i
:
for (var i = 0; i < 5; i++) {
setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/);
}
... цикл неожиданно выводит "i is 5" пять раз:
i is 5
i is 5
i is 5
i is 5
i is 5
person
mormegil
schedule
22.05.2017
let
включен в черновик 6-го издания и, скорее всего, будет в окончательной спецификации. - person Richard Ayotte   schedule 31.03.2012