JS: присваивание без var/let/const и область видимости

Есть блок кода, в котором объявляются переменные и объявлены следующим образом:

a=3; b=«hello»;

Укажите правильное утверждение:

Теория: что происходит при `a=3`

В JavaScript важно различать:

  • объявление переменной (var, let, const);
  • присваивание значения идентификатору (a = 3).

Если выполняется присваивание a = 3, но идентификатор a ранее не был объявлен в текущей области видимости или во внешних областях, то это называется присваиванием необъявленному идентификатору (по смыслу — “переменной, которой нет”). Дальше поведение зависит от режима кода:

  • нестрогий режим (sloppy mode): движок обычно создаёт свойство глобального объекта, из‑за чего появляется глобальная переменная;
  • строгий режим (strict mode): такое присваивание запрещено и приводит к ошибке выполнения ReferenceError.
Строгий режим включается директивой "use strict"; внутри файла или функции. В JavaScript-модулях строгий режим действует автоматически, даже без этой директивы.

Упрощённая схема решения для подобных задач:

Присваивание `a = 3`
|
v
Проверка: объявлена ли `a` через `var/let/const` (или как параметр функции)?
|
+-- Да -> изменяется существующая переменная `a` в найденной области видимости
|
+-- Нет -> проверка режима:
         - sloppy -> появляется глобальная привязка (через глобальный объект)
         - strict -> `ReferenceError` (ошибка выполнения)
В исходной записи b=«hello»; используются кавычки-ёлочки « », которые не являются строковыми кавычками JavaScript. Для строк подходят '...', "..." или `...`.

Разбор утверждений (что верно)

Ниже оцениваются утверждения именно для кода вида a=3; b="hello";, то есть без var/let/const.

УтверждениеОценкаПочему
Создание переменной без ключевого слова var — синтаксическая ошибкаНеверноЭто не “ошибка синтаксиса” (код обычно разбирается), а ошибка выполнения в строгом режиме (ReferenceError) или создание глобальной переменной в нестрогом режиме.
Создаются в локальном контекстеНеверноЛокальные переменные возникают при объявлении (let/const в блоке, var в функции и т.п.). Присваивание необъявленному идентификатору не создаёт “локальную” переменную.
Создаются в глобальном контекстеЗависит от режимаВ нестрогом режиме обычно появляется глобальная переменная (как свойство глобального объекта). В строгом режиме ничего не создаётся — выполнение прерывается ReferenceError.

Вывод для тестового формата:

  • “синтаксическая ошибка” — неверно;
  • “локальный контекст” — неверно;
  • “глобальный контекст” — верно только при уточнении “в нестрогом режиме”.

Примеры: sloppy, strict, module

Пример 1 — нестрогий режим (sloppy): появляется глобальная переменная

(function () {
  a = 3;
  b = "hello";
})();

console.log(globalThis.a); // 3
console.log(globalThis.b); // "hello"

Смысл: хотя присваивание находится внутри функции, при отсутствии объявления идентификаторы “утекают” в глобальную область (как свойства глобального объекта), что делает поведение неочевидным.

Пример 2 — строгий режим (strict): возникает ReferenceError

(function () {
  "use strict";
  a = 3;        // ReferenceError
  b = "hello";  // выполнение до этой строки обычно не дойдёт
})();

Смысл: строгий режим специально запрещает “случайное” создание глобальных переменных, чтобы ошибки находились раньше и код был безопаснее.

Пример 3 — модуль (ESM): строгий режим включён автоматически

// file: app.mjs (или <script type="module"> в браузере)
a = 3;        // ReferenceError
b = "hello";  // ReferenceError

Смысл: в модуле нельзя рассчитывать на поведение sloppy-режима; требуется явное объявление переменных.

Если в одних местах проекта код выполняется как модуль, а в других как обычный скрипт, то один и тот же фрагмент a=3 может “работать” в одном месте и падать с ошибкой в другом. Это частая причина трудной отладки.

Как правильно объявлять `a` и `b` + подсказка

Корректные варианты с явным объявлением:

const a = 3;
const b = "hello";

let a = 3;
let b = "hello";
a = 4;
b = "hi";

Если действительно требуется именно глобальная переменная, то более явно и читаемо задавать её через глобальный объект:

globalThis.a = 3;
globalThis.b = "hello";

Кратко: a=3; b="hello"; без var/let/const не даёт синтаксическую ошибку, не создаёт локальные переменные, а в нестрогом режиме обычно создаёт глобальные (через globalThis), тогда как в строгом режиме и в модулях приводит к ReferenceError, поэтому утверждение про “глобальный контекст” верно только при указании нестрогого режима.