Разберите семантику и тонкие места JavaScript на примере: console.log(a); var a = 1; function f(){ console.log(this); } const g = ()=>console.log(this); f(); g(); — объясните порядок объявления, поднятие (hoisting), поведение this в разных функциях и какие ошибки из-за этого часто встречаются у новичков

23 Окт в 12:45
2 +1
0
Ответы
1
Коротко и по делу — разберу по пунктам на вашем примере.
Исходный код:
console.log(a);
var a = 1;
function f(){ console.log(this); }
const g = ()=>console.log(this);
f();
g();
1) Hoisting (поднятие) и порядок объявления
- `var` — объявление поднимается вверх функции/скрипта, инициализируется значением `undefined`. Присваивание остаётся на месте. Поэтому
- `console.log(a);` выведет `undefined`.
- `var a = 1;` — здесь происходит присваивание `111` после логирования.
- `function` (function declaration) — поднимается полностью (объявление + тело). Функцию можно вызывать до строки её объявления.
- `let/const` — объявление попадает в TDZ (temporal dead zone). Доступ до инициализации вызывает `ReferenceError`. Вызов `g` до `const g = ...` даст ошибку.
- Пример:
- `console.log(a); // undefined` (при `var a = 111`)
- `console.log(b); // ReferenceError`, если `let b = 2;`
2) Поведение this
- Обычная функция (`function f(){ ... }`) — значение `this` определяется вызовом:
- при вызове как `obj.f()` — `this === obj`;
- при простом вызове `f()` в не‑строгом глобальном скрипте — `this === window` (браузер);
- при простом вызове в строгом режиме или в модуле — `this === undefined`.
- Стрелочная функция (`const g = ()=>...`) — НЕ имеет собственного `this`. Она захватывает (лексически) `this` внешней области, где она определена (то есть значение `this` фиксируется при объявлении).
- Если `g` объявлена в глобальной не‑строгой области, внешнее `this` — `window` → `g()` выведет `window`.
- Если `g` объявлена в функции/модуле со `this === undefined`, то `g()` выведет `undefined`.
3) Что произойдёт в вашем примере (типичный сценарий)
- В обычном (не‑модульном, нестрогом) браузерном скрипте:
- `console.log(a);` → `undefined`
- `f();` → выведет `window`
- `g();` → выведет `window` (стрелка захватила глобальный `this`)
- В ES6‑модуле или при `"use strict"`:
- `console.log(a);` → `undefined` (var всё равно поднимается)
- `f();` → `undefined` (обычная функция в строгом режиме при простом вызове)
- `g();` → `undefined` (стрелка захватила внешний `this`, который равен `undefined`)
4) Частые ошибки у новичков
- Ожидание, что `console.log(a)` перед `var a = 1` выведет `1` — вместо этого `undefined`.
- Попытка вызвать переменную `let/const` до объявления → `ReferenceError`.
- Использование стрелочной функции как метода объекта, ожидая, что `this` будет ссылаться на объект:
- `obj = { m: ()=>console.log(this) }; obj.m();` — часто печатает не `obj`, потому что стрелка не имеет `this`.
- Потеря контекста при передаче метода в колбэк:
- `setTimeout(obj.method, 0);` — внутри `method` `this` может быть `window`/`undefined`. Решение: привязать `obj.method.bind(obj)` или использовать стрелку/замыкание.
- Попытка перезаписать `const` или повторно объявить `let`/`const` — ошибки.
5) Резюме (ключевые тезисы)
- `var` — declaration hoisted, value `undefined` until assignment.
- `function` declarations — hoisted with body.
- `let/const` — TDZ, access before init → `ReferenceError`.
- `this` in ordinary functions = depends on call-site; in arrow functions = lexical (captured at definition).
- Ошибки: TDZ, неверные ожидания `hoisting`, неверное поведение `this` при стрелках и при передаче методов как колбэков.
Если нужно, могу показать короткие варианты кода с `console.log` и ожидаемым выводом для разных сред (браузер/модуль/Node).
23 Окт в 13:13
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир