объясните понятия hoisting, замыкания и лексической области видимости и приведите несколько способов исправления (ES5/ES6)

14 Окт в 14:55
3 +1
0
Ответы
1

Hoisting (поднятие)

Что это: механизм, при котором объявления переменных и функций логически перемещаются в начало их текущей области видимости во время фазы компиляции. При этом:
объявления функций (function declaration) поднимаются полностью — можно вызывать до места объявления;объявления через var поднимаются, но инициализация выполняется в месте присвоения — до присвоения значение undefined.let/const и class объявляются тоже «логически поднятыми», но доступны в temporal dead zone (TDZ) до фактической инициализации.Проблемы: неожиданные undefined, вызовы неинициализированных значений, ошибки в логике.

Способы исправления:

ES6: использовать let/const вместо var (устраняет нежелательное поведение).ES6: объявлять функции как const/let-значения (function expressions / arrow functions) — они не поднимаются как function declaration.Общая практика: объявлять переменные и функции до их использования (top-down code).ES5 (если нужно ограничить область видимости): использовать IIFE, чтобы контролировать видимость и инициализацию.

Closure (замыкание)

Что это: функция вместе с «захваченными» внешними переменными из лексической области видимости, даже когда внешняя функция уже завершила выполнение. Замыкание хранит ссылки на те переменные, к которым есть доступ.Пример полезного применения: фабрика функций, приватные счётчики, сохранение состояния.

Типичный подвох + исправления:

Проблема: цикл с var и отложенными колбэками — все колбэки видят одно и то же финальное значение переменной.
ES5-исправление: IIFE для захвата текущего значения:
for (var i = 0; i < 3; i++) {
(function(j) {
setTimeout(function() { console.log(j); }, 100);
})(i);
}ES6-исправление: использовать let в заголовке цикла — для каждой итерации создаётся своя привязка:
for (let i = 0; i < 3; i++) {
setTimeout(() => console.log(i), 100);
}Альтернатива: фабрика функций:
function makeLogger(x) { return function() { console.log(x); }; }

Lexical scope (лексическая область видимости)

Что это: правило, по которому принадлежность переменной к области видимости определяется по месту объявления в исходном коде (а не по месту вызова). Вложенные функции имеют доступ к переменным внешних функций, и это определяется статически.Отличие от динамической области видимости: при лексической — поиск переменных идёт по структуре кода вверх; при динамической — по стеку вызовов (JS использует лексическую).

Примеры и советы:

Лексическая область — основа замыканий: внутренняя функция всегда «видит» внешние переменные, которые были в момент её объявления.
function outer(x) {
let y = x + 1;
function inner() {
return y; // лексически связана с outer
}
return inner;
}Чтобы избежать ошибок с областью видимости:
ES6: предпочитать let/const для блочной области видимости.ES5: при необходимости создавать новый scope через IIFE.Явно передавать значения в функции вместо опоры на внешние переменные, если нужно чистое поведение.

Коротко — практические рекомендации

Используйте let/const (ES6) вместо var.Объявляйте функции/переменные до использования, когда это возможно.Для исправления проблем с замыканиями в ES5 используйте IIFE или фабрики функций; в ES6 — let в циклах и стрелочные функции, если нужен лексический this.Понимайте, что лексическая область видимости — причина замыканий и ключ к прогнозируемому поведению кода.
14 Окт в 16:46
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир