This page was translated from English by the community.Learn more and join the MDN Web Docs community.
let
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since сентябрь 2016 г..
Директиваlet объявляет переменную с блочной областью видимости с возможностью инициализировать её значением.
In this article
Синтаксис
let var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]];
Параметры
var1,var2, …,varNИмя переменной. Может использоваться любой допустимый идентификатор.
value1,value2, …,valueNЗначение переменной. Любое допустимое выражение.
Описание
Директиваlet позволяет объявить локальную переменную с областью видимости, ограниченной текущим блоком кода . В отличие от ключевого словаvar, которое объявляет переменную глобально или локально во всей функции, независимо от области блока.
Объяснение, почему было выбрано название "let" можно найтиздесь.
Правила области видимости
Областью видимости переменных, объявленных ключевым словомlet, является блок, в котором они объявлены, и все его подблоки. В этом работа директиваlet схожа с работой директивыvar. Основная разница заключается в том, что областью видимости переменной, объявленной директивойvar, является вся функция, в которой она объявлена:
function varTest() { var x = 1; if (true) { var x = 2; // та же переменная! console.log(x); // 2 } console.log(x); // 2}function letTest() { let x = 1; if (true) { let x = 2; // другая переменная console.log(x); // 2 } console.log(x); // 1}Чище код во вложенных функциях
let иногда делает код чище при использовании вложенных функций.
var list = document.getElementById("list");for (let i = 1; i <= 5; i++) { let item = document.createElement("li"); item.appendChild(document.createTextNode("Item " + i)); item.onclick = function (ev) { console.log("Item " + i + " is clicked."); }; list.appendChild(item);}// чтобы получить такой же эффект с использованием 'var'// необходимо создать новый контекст// используя замыкание, чтобы сохранить значение неизменённымfor (var i = 1; i <= 5; i++) { var item = document.createElement("li"); item.appendChild(document.createTextNode("Item " + i)); (function (i) { item.onclick = function (ev) { console.log("Item " + i + " is clicked."); }; })(i); list.appendChild(item);}Пример выше будет выполнен как и ожидается, так как пять экземпляров внутренней функции (анонимной) будут ссылаться на пять разных экземпляров переменнойi. Пример будет выполнен неверно, если заменить директивуlet наvar, или удалить переменнуюi из параметров вложенной функции и использовать внешнюю переменнуюi во внутренней функции.
На верхнем уровне скриптов и функцийlet, в отличии от var, не создаёт свойства на глобальном объекте. Например:
var x = "global_x";let y = "global_y";console.log(this.x); // 'global_x'console.log(this.y); // undefinedВ выводе программы будет отображено слово "global_x" дляthis.x, ноundefined дляthis.y.
Эмуляция приватных членов
При взаимодействии сконструкторами можно использовать выражениеlet чтобы открыть доступ к одному или нескольким приватным членам через использованиезамыканий:
var SomeConstructor;{ let privateScope = {}; SomeConstructor = function SomeConstructor() { this.someProperty = "foo"; privateScope.hiddenProperty = "bar"; }; SomeConstructor.prototype.showPublic = function () { console.log(this.someProperty); // foo }; SomeConstructor.prototype.showPrivate = function () { console.log(privateScope.hiddenProperty); // bar };}var myInstance = new SomeConstructor();myInstance.showPublic();myInstance.showPrivate();console.log(privateScope.hiddenProperty); // errorЭта техника позволяет получить только "статичное" приватное состояние - в примере выше, все экземпляры полученные из конструктораSomeConstructor будут ссылаться на одну и ту же область видимостиprivateScope.
Временные мёртвые зоны и ошибки при использованииlet
Повторное объявление той же переменной в том же блоке или функции приведёт к выбросу исключенияSyntaxError.
if (x) { let foo; let foo; // SyntaxError thrown.}В стандарте ECMAScript 2015 переменные, объявленные директивой let, переносятся в начало блока. Но если вы сошлётесь в блоке на переменную, до того как она объявлена директивой let, то это приведёт к выбросу исключенияReferenceError, потому что переменная находится во "временной мёртвой зоне" с начала блока и до места её объявления. (В отличии от переменной, объявленной черезvar, которая просто будет содержать значениеundefined)
function do_something() { console.log(bar); // undefined console.log(foo); // ReferenceError: foo is not defined var bar = 1; let foo = 2;}Вы можете столкнуться с ошибкой в операторах блокаswitch, так как он имеет только один подблок.
switch (x) { case 0: let foo; break; case 1: let foo; // Выброс SyntaxError из-за повторного объявления переменной break;}Использованиеlet в циклахfor
Вы можете использовать ключевое словоlet для привязки переменных к локальной области видимости циклаfor. Разница с использованиемvar в заголовке циклаfor, заключается в том, что переменные объявленныеvar, будут видны во всей функции, в которой находится этот цикл.
var i = 0;for (let i = i; i < 10; i++) { console.log(i);}Правила области видимости
for (let expr1; expr2; expr3) statement;В этом примереexpr2, *expr3, statement *заключены в неявный блок, который содержит блок локальных переменных, объявленных конструкциейlet expr1. Пример приведён выше.
Примеры
>let vsvar
Когда let используется внутри блока, то область видимости переменной ограничивается этим блоком. Напомним, что отличие заключается в том, что областью видимости переменных, объявленных директивой var, является вся функция, в которой они были объявлены.
var a = 5;var b = 10;if (a === 5) { let a = 4; // The scope is inside the if-block var b = 1; // The scope is inside the function console.log(a); // 4 console.log(b); // 1}console.log(a); // 5console.log(b); // 1let в циклах
Вы можете использовать ключевое словоlet для привязки переменных к локальной области видимости циклаfor, вместо того что бы использовать глобальные переменные (объявленные с помощьюvar).
for (let i = 0; i < 10; i++) { console.log(i); // 0, 1, 2, 3, 4 ... 9}console.log(i); // i is not definedНестандартизированные расширенияlet
>let блок
Предупреждение:Поддержкаlet блоков была убрана в Gecko 44Firefox bug 1023609.
let блок предоставляет способ, ассоциировать значения с переменными внутри области видимости этого блока, без влияния на значения переменных с теми же именами вне этого блока.
Синтаксис
let (var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]]) block;Описание
let блок предоставляет локальную область видимости для переменных. Работа его заключается в привязке нуля или более переменных к области видимости этого блока кода, другими словами, он является блоком операторов. Отметим, что область видимости переменных, объявленных директивойvar, вблокеlet, будет той же самой, что и если бы эти переменные были объявлены внеблокаlet, иными словами областью видимости таких переменных по-прежнему является функция. Скобки вблокеlet являются обязательными. Опускание их приведёт к синтаксической ошибке.
Пример
var x = 5;var y = 0;let (x = x+10, y = 12) { console.log(x+y); // 27}console.log(x + y); // 5Правила для этого блока кода аналогичны как и для любого другого блока кода в JavaScript. Он может содержать свои локальные переменные, объявленныеlet.
Правила области видимости
Областью видимости переменных, объявленных директивойlet, вблокеlet является сам блок и все подблоки в нем, если они не содержат объявлений переменных с теми же именами.
let выражения
Предупреждение:Поддержкаlet была убрана в Gecko 41Firefox bug 1023609.
let выражение позволяет объявить переменные с областью видимости ограниченной одним выражением.
Синтаксис
let (var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]]) expression;
Пример
Вы можете использовать let для объявления переменных, областью видимости которых является только одно выражение:
var a = 5;let(a = 6) console.log(a); // 6console.log(a); // 5Правила области видимости
В данномlet выражении:
let (decls) expr*expr *оборачивается в неявный блок.
Спецификации
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-let-and-const-declarations> |