Временная мертвая зона (TDZ – Temporal Dead Zone) в JS

Временная мертвая зона (Temporal Dead Zone) – термин, обозначающий состояние, в котором переменные недоступны. Они находятся в области видимости (scope), но не объявлены (not declared).

Переменные объявленные через let и const существуют в области TDZ от начала их в области видимости до момента их декларирования (объявления).

{
	//***
	//This is the temporal dead zone for the age variable!
	//Если мы обращаемся к age тут, то мы получаем ReferenceError:
	console.log(age); //Uncaught ReferenceError: Cannot access 'age' before initialization
 	// This is the temporal dead zone for the age variable!
	//***
	let age; // Объявление переменной. Теперь TDZ больше нет. Т.е. как только переменная декларирована (объявлена), то TDZ для этой переменной пропадает.
	age = 27;
}

var – исключение:
В JavaScript переменные, объявленные с использованием var, не имеют так называемой временной мёртвой зоны (Temporal Dead Zone, TDZ).
Переменные var существуют с начала их охватывающей области видимости (функции или глобальной области видимости), и они инициализируются значением undefined

console.log(age) //uderfinded. для var нет понятия TDZ
var age;
age = 28;

В чем разница между объявлением (declaration) и инициализацией (inicialization)?

function scopeExample() {

    let age; // 1. Объявление (Declaring) переменной означает, что мы резервируем имя в памяти в текущей области видимости (scope).
    age = 20; // 2. Инициализация переменной (Initialising a variable) — это установка значения переменной (setting the value of the variable).
    let hands = 2; // 3. также мы можем совместить 1. и 2.
}

Примеры, где можно встретить TDZ:

function createTDZ(a=b, b) {
}
createTDZ(undefined, 1);
//Выведет: Cannot access 'b' before initialization
//Поскольку при вычислении значения переменной a, идет обращение к переменной b, которая еще не пропарсена движком JS.
let tdzTest = tdzTest;
//ReferenceError: Cannot access 'tdzTest' before initialization

Но аналогичный код с var уже не вызовет ошибки:

var tdzTest = tdzTest; //underfined

И заключительный пример от Erik Arvindson, который участвует в разработке и поддержке спецификации ECMAScript:

let a = f(); // 1
const b = 2;
function f() { return b; } // 2, b is in the TDZ

В первой строке мы вызываем f функцию, а затем пытаемся получить доступ к b переменной (которая выдает ошибку ReferenceError. Поскольку b находится в TDZ).

Зачем нам нужен TDZ?

Alex Написал статью, в которой рассказывает об этом.

  • Это помогает нам ловить ошибки;
  • Попытка получить доступ к переменной до того, как она будет объявлена, является неправильным способом и не должна быть возможной;

Избежать ошибок, связанных с TDZ довольно просто, достаточно объявлять переменные в верху области видимости.

На основе: https://www.freecodecamp.org/news/what-is-the-temporal-dead-zone/

Задачи:

Что выведет данный код?

Взято с: https://learn.javascript.ru/task/let-scope

let x = 1;

function func() {
  console.log(x); // ?

  let x = 2;
}

func();
Ответ Переменная находится в «неинициализированном» («uninitialized») состоянии с момента входа в блок кода (или функцию). И остается неинициализированной до соответствующего оператора let. Другими словами, переменная технически существует, но не может быть использована до let.

function func() {
  // локальная переменная x известна движку с самого начала выполнения функции,
  // но она неинициализированна ("uninitialized") до let ("мёртвая зона")
  // следовательно, ошибка

  console.log(x); // ReferenceError: Cannot access 'x' before initialization

  let x = 2;
}

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *