<MyRusakov.ru />

Профессиональная Web-разработка. Дизайн, код и автоматизация

Профессиональная Web-разработка. Дизайн, код и автоматизация

Это очень подробный курс из разряда "всё включено". Разбираются следующие темы: HTML, CSS, SCSS, JavaScript, PHP, SQL, Laravel, Nginx, PostCSS, npm, Vite, Vitest, Composer, PHPUnit, Prettier, Stylelint, ESLint, Pint, Larastan, Git, Agile, Scrum, Docker, Supervisord, Figma, Stitch AI, Confluence, Jira.

Рассчитан и на новичков, и на тех, кто уже знаком с основами, но хочет освоить полный цикл разработки.

Помимо самой теории, Вы увидите пример создания Web-проекта на 20 000 строк кода: от идеи и документации на Confluence через планирование на Jira, fullstack-разработку до деплоя на VPS.

Помимо уроков, курс содержит упражнения для закрепления знаний и финальное тестирование. А ещё Вы получите 5 полноценных Бонусных курсов: «GitLab под ключ», «Вёрстка сайта с нуля 2.0», «JavaScript с Нуля до Гуру 2.0», «PHP и MySQL с Нуля до Гуру 3.0» и «Laravel от А до Я».

Подробнее
Подписка

Подпишитесь на мой канал на YouTube, где я регулярно публикую новые видео.

YouTube Подписаться

Подписавшись по E-mail, Вы будете получать уведомления о новых статьях.

Подписка Подписаться

Добавляйтесь ко мне в друзья ВКонтакте! Отзывы о сайте и обо мне оставляйте в моей группе.

Мой аккаунт Мой аккаунт Моя группа
Опрос

Какая тема Вас интересует больше?

Hoisting и области видимости в JavaScript: var, let, const и TDZ простыми словами

Hoisting и области видимости в JavaScript: var, let, const и TDZ простыми словами

Если вы когда-нибудь видели, как переменная оказывается «доступной» до места своего объявления, вы сталкивались с hoisting (поднятием). В этой статье простыми словами разберём hoisting в JavaScript, области видимости (глобальная, функциональная и блочная), var против let/const, TDZ, поведение функций и типичные ловушки. Материал ориентирован на запрос «hoisting в JavaScript простыми словами» и поможет уверенно писать код без неожиданных ошибок.

Что такое hoisting (поднятие)?

Hoisting — это процесс, при котором объявления переменных и функций как бы «перемещаются» интерпретатором в верхнюю часть своей области видимости на этапе компиляции. Важно: поднимаются объявления, а не инициализации.

console.log(a); // undefined (объявление var поднято, значение ещё не присвоено)
var a = 10;

console.log(foo()); // "ok" — объявления функций (function declaration) поднимаются целиком
function foo() { return "ok"; }

console.log(typeof bar); // "undefined" — bar есть как переменная, но ещё без значения
try {
  bar();
} catch (e) {
  console.log(e.name); // TypeError: bar не функция (пока undefined)
}
var bar = function () { return "bar"; };

Объявления функций (function declaration) поднимаются вместе с телом, а функциональные выражения (function expression) — нет: поднимается только переменная (при var) со значением undefined до инициализации.

var, let, const и блочная область видимости

Ключевое отличие: var — функциональная область видимости, а let/const — блочная. Это влияет на доступность переменных внутри if, for, while и т. п.

if (true) {
  var x = 1;
  let y = 2;
  const z = 3;
}
console.log(x); // 1 — var «протёк» наружу (функциональная область)
console.log(typeof y); // ReferenceError — y виден только внутри блока
console.log(typeof z); // ReferenceError — z тоже только внутри блока

Дополнительно: в браузере глобальный var попадает на window, а глобальные let/const — нет.

// В браузере:
var g1 = 1;
let g2 = 2;
console.log(window.g1); // 1
console.log(window.g2); // undefined

TDZ: Temporal Dead Zone — почему let/const «не доступны» до объявления

let и const тоже поднимаются, но попадают в зону временной мёртвости (TDZ), пока не достигнута строка объявления. Любой доступ до объявления бросит ReferenceError, даже typeof!

try {
  console.log(b);
} catch (e) {
  console.log(e.name); // ReferenceError
}
let b = 5;

try {
  console.log(typeof c);
} catch (e) {
  console.log(e.name); // ReferenceError — даже typeof не спасает в TDZ
}
let c;

Функциональные выражения на let/const тоже подчиняются TDZ:

try {
  baz();
} catch (e) {
  console.log(e.name); // ReferenceError
}
let baz = () => "baz";

for и замыкания: почему var ломает таймеры

Классическая ловушка с var в цикле: все колбэки «видят» одно и то же i, которое к моменту выполнения уже изменилось.

for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 0);
}
// 3, 3, 3

for (let j = 0; j < 3; j++) {
  setTimeout(() => console.log(j), 0);
}
// 0, 1, 2 — у let своя блочная область на каждую итерацию

Исторический обходной путь с IIFE для var:

for (var i = 0; i < 3; i++) {
  (function(i) {
    setTimeout(() => console.log(i), 0);
  })(i);
}

Функции: объявления против выражений

Ещё раз кратко: function declaration поднимается целиком и может вызываться до места записи; function expression — нет.

greet(); // работает
function greet() { console.log("Привет!"); }

try {
  speak();
} catch (e) {
  console.log(e.name); // TypeError или ReferenceError в зависимости от var/let
}
var speak = function() { console.log("Говорю"); };

Строгий режим и утечки глобальных переменных

Hoisting не отключается строгим режимом, но strict-mode блокирует неявное создание глобалок присваиванием без объявления — частый друг багов с поднятием.

function demo() {
  'use strict';
  try {
    ghost = 42; // без объявления
  } catch (e) {
    console.log(e.name); // ReferenceError
  }
}

demo();

Типичные ошибки и как их избежать

  • Использование переменной до объявления: включите правило ESLint no-use-before-define и старайтесь объявлять переменные ближе к месту использования.
  • var в циклах и блоках: отдавайте приоритет let и const — они блочно-областные и безопаснее.
  • Переопределение: var позволяет повторно объявлять переменные в одной области — ловушка для отладки. let/const такого не допускают.
  • const не означает «неизменяемый объект»: нельзя переassign’ить ссылку, но менять свойства можно.
const user = { name: "Ann" };
user.name = "Ben"; // ок
// user = {} ; // TypeError — переназначить нельзя

Рекомендации по стилю и архитектуре

  • По умолчанию используйте const; переходите на let, когда действительно нужна переназначаемая переменная.
  • Избегайте var в современном коде. Он нужен только для совместимости со старым кодом или специфическими средами.
  • Не полагайтесь на hoisting для «магии». Объявляйте функции и переменные до использования — код станет предсказуемее.
  • Включайте ESLint: no-use-before-define, prefer-const, block-scoped-var помогут отловить ошибки ранней стадии.

Мини-чеклист по hoisting в JavaScript

  • var — функциональная область; объявления поднимаются как undefined.
  • let/const — блочная область; есть TDZ до строки объявления (ReferenceError).
  • Function declaration поднимается целиком; function expression — нет.
  • Для циклов и асинхронных колбэков используйте let, чтобы избежать «общего» индекса.
  • Строгий режим не убирает hoisting, но предотвращает неявные глобальные переменные.

Хотите быстро закрепить тему на практике и закрыть пробелы в основах и продвинутых приёмах? Рекомендую пройти практический курс «JavaScript с Нуля до Гуру 2.0» — прокачайте навыки на реальных задачах.

Итоги

Понимание hoisting и областей видимости — фундамент для уверенного JavaScript. Освойте разницу между var, let и const, не забывайте про TDZ, аккуратно используйте функции и держите код линтимым. Так вы избежите самых коварных багов и ускорите разработку в реальных проектах.

Копирование материалов разрешается только с указанием автора (Михаил Русаков) и индексируемой прямой ссылкой на сайт (https://myrusakov.ru)!

Добавляйтесь ко мне в друзья ВКонтакте: https://vk.com/myrusakov.
Если Вы хотите дать оценку мне и моей работе, то напишите её в моей группе: https://vk.com/rusakovmy.

Если Вы не хотите пропустить новые материалы на сайте,
то Вы можете подписаться на обновления: Подписаться на обновления

Если у Вас остались какие-либо вопросы, либо у Вас есть желание высказаться по поводу этой статьи, то Вы можете оставить свой комментарий внизу страницы.

Порекомендуйте эту статью друзьям:

Если Вам понравился сайт, то разместите ссылку на него (у себя на сайте, на форуме, в контакте):

  1. Кнопка:

    Она выглядит вот так: Как создать свой сайт

  2. Текстовая ссылка:

    Она выглядит вот так: Как создать свой сайт

  3. BB-код ссылки для форумов (например, можете поставить её в подписи):

Комментарии (0):

Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.