--- title: let slug: Web/JavaScript/Reference/Statements/let tags: - ECMAScript 2015 - JavaScript - let - змінні translation_of: Web/JavaScript/Reference/Statements/let ---
{{jsSidebar("Statements")}}

Оператор let оголошує локальну змінну блочної області видимості, з необов'язковим присвоєнням їй початкового значення.

{{EmbedInteractiveExample("pages/js/statement-let.html")}}

Синтаксис

let var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN];

Параметри

var1, var2, …, varN
Імена змінної або змінних, що оголошуються. Кожне ім'я має бути дозволеним ідентифікатором JavaScript.
value1, value2, …, valueN {{optional_inline}}
Для кожної оголошеної змінної ви можете вказати її початкове значення будь-яким дозволеним виразом JavaScript.

Опис

Оператор let дозволяє оголошувати змінні, що обмежені областю видимості {{jsxref("statements/block", "блоку")}} або виразу, для якого використовуються, на відміну від ключового слова {{jsxref("statements/var", "var")}}, яке визначає змінну глобально, чи локально для всієї функції, незалежно від області видимості блоку. Інша відмінність між операторами {{jsxref("statements/var", "var")}} та let полягає в тому, що останній ініціалізується тільки після оцінювання синтаксичним аналізатором (дивіться нижче).

Як і {{jsxref("statements/const", "const", "Description")}}, let не створює властивостей об'єкта {{domxref('window')}} при глобальному оголошенні (у області видимості верхнього рівня).

Пояснення, чому була обрана назва "let" можна подивитись тут.

Правила області видимості

Областю видимості змінних, оголошених через let, є блок, у якому вони визначені, а також будь-які вкладені в нього блоки. У цьому сенсі let дуже схожий на var. Головна відмінність полягає в тому, що областю видимості змінної var є уся замикаюча функція:

function varTest() {
  var x = 1;
  {
    var x = 2;  // та сама змінна!
    console.log(x);  // 2
  }
  console.log(x);  // 2
}

function letTest() {
  let x = 1;
  {
    let x = 2;  // інша змінна
    console.log(x);  // 2
  }
  console.log(x);  // 1
}

На верхньому рівні програм та функцій let, на відміну від var, не створює властивості глобального об'єкта. Наприклад:

var x = 'глобальна';
let y = 'глобальна';
console.log(this.x); // "глобальна"
console.log(this.y); // undefined

Імітація приватних членів

Працюючи з конструкторами, можна використовувати let-зв'язування для створення приватних членів без використання замикань:

var Thing;

{
  let privateScope = new WeakMap();
  let counter = 0;

  Thing = function() {
    this.someProperty = 'foo';

    privateScope.set(this, {
      hidden: ++counter,
    });
  };

  Thing.prototype.showPublic = function() {
    return this.someProperty;
  };

  Thing.prototype.showPrivate = function() {
    return privateScope.get(this).hidden;
  };
}

console.log(typeof privateScope);
// "undefined"

var thing = new Thing();

console.log(thing);
// Thing {someProperty: "foo"}

thing.showPublic();
// "foo"

thing.showPrivate();
// 1

Такий самий шаблон приватності з використанням замикань для локальних змінних можна створити через var, але це потребує функціональної області видимості (зазвичай, це НВФВ у шаблоні модуль) замість просто блочної області видимості у вищенаведеному прикладі.

Повторні оголошення

Повторне оголошення тієї самої змінної у області видимості тієї самої функції чи блоку спричиняє помилку {{jsxref("SyntaxError")}}.

if (x) {
  let foo;
  let foo; // викидається SyntaxError.
}

Ви можете стикнутися з помилками у конструкціях switch, бо вони мають лише один блок.

let x = 1;
switch(x) {
  case 0:
    let foo;
    break;

  case 1:
    let foo; // SyntaxError через повторне оголошення.
    break;
}

Однак, важливо зазначити, що блок, вкладений у блок case, створить нове лексичне середовище блочної області видимості, яке не викличе помилок повторного оголошення, показаних вище.

let x = 1;

switch(x) {
  case 0: {
    let foo;
    break;
  }
  case 1: {
    let foo;
    break;
  }
}

Тимчасова мертва зона

На відміну від змінних, оголошених через var, які спочатку мають значення undefined, let-змінні не ініціалізуються, поки не відбудеться обчислення їхнього оголошення. Звернення до змінної до ініціалізації призводить до викидання ReferenceError. Змінна знаходиться у "тимчасовій мертвій зоні" від початку блоку і до проходження ініціалізації.

function do_something() {
  console.log(bar); // undefined
  console.log(foo); // ReferenceError
  var bar = 1;
  let foo = 2;
}

Тимчасова мертва зона та typeof

На відміну від просто неоголошених змінних та змінних, що містять значення undefined, використання оператора typeof для перевірки типу змінної, що знаходиться у своїй ТМЗ, викине ReferenceError:

// виведе 'undefined'
console.log(typeof undeclaredVariable);
// призведе до 'ReferenceError'
console.log(typeof i);
let i = 10;

Ще один приклад тимчасової мертвої зони у поєднанні з лексичною областю видимості

Через наявність лексичної області видимості, ідентифікатор foo у виразі (foo + 55) оцінюється як ідентифікатор foo блоку if, а не розташована вище змінна foo зі значенням 33.

У цьому конретному рядку змінна foo блоку if вже була створена у лексичному середовищі, але ще не пройшла (і перервала) свою ініціалізацію (яка є частиною інструкції).

Змінна foo блоку if досі у тимчасовій мертвій зоні.

function test(){
   var foo = 33;
   if (true) {
      let foo = (foo + 55); // ReferenceError
   }
}
test();

Цей феномен може заплутати, наприклад, у наступній ситуації. Інструкція let n of n.a вже знаходиться всередині приватної області видимості блоку циклу for. Отже, ідентифікатор n.a вважається властивістю 'a' об'єкта 'n', розташованого у першій частині цієї ж інструкції ("let n").

Він досі знаходиться у тимчасовій мертвій зоні, оскільки його оголошення ще не було виконано та перервалось.

function go(n) {
  // n тут визначений!
  console.log(n); // Object {a: [1,2,3]}

  for (let n of n.a) { // ReferenceError
    console.log(n);
  }
}

go({a: [1, 2, 3]});

Інші ситуації

При використанні всередині блоку, let обмежує область видимості змінної цим блоком. Зауважте відмінність від var, чия область видимості - функція, де відбулось оголошення.

var a = 1;
var b = 2;

if (a === 1) {
  var a = 11; // глобальна область видимості
  let b = 22; // областю видимості є блок if

  console.log(a);  // 11
  console.log(b);  // 22
}

console.log(a); // 11
console.log(b); // 2

Однак, комбінація оголошень var та let, наведена нижче, спричинить SyntaxError через підняття var наверх блоку. Це призводить до неявного повторного оголошення змінної.

let x = 1;

{
  var x = 2; // SyntaxError через повторне оголошення
}

Специфікації

Специфікація Статус Коментар
{{SpecName('ES2015', '#sec-let-and-const-declarations', 'Let and Const Declarations')}} {{Spec2('ES2015')}} Початкове визначення. Не визначає let-вирази та let-блоки.
{{SpecName('ESDraft', '#sec-let-and-const-declarations', 'Let and Const Declarations')}} {{Spec2('ESDraft')}}

Сумісність з веб-переглядачами

{{Compat("javascript.statements.let")}}

Див. також