Перейти к содержимому
Теория · Область видимости · урок 7 из 8

Глобальные переменные и строгий режим

Квартира с комнатами стоит в многоквартирном доме. Вещь, оставленную на лестнице в подъезде, видят жильцы всех квартир, и любой из них может её переставить. В программе такой лестнице соответствует верхний уровень файла, вне всех функций и блоков.

Опечатка в имени переменной не всегда останавливает программу. Здесь в функции add вместо total написано totl, но ошибки нет:

JavaScript
let total = 0;

function add(n) {
    totl = total + n;
}

add(5);
console.log(total); // 0
console.log(totl); // 5

Давайте разберём, что произошло:

  1. add(5) выполняет строку totl = total + n, и справа от = получается 5.
  2. Имя totl нигде не объявлено, но программа не останавливается: появляется новая переменная totl со значением 5.
  3. total никто не менял, и программа печатает 0.
  4. Новую totl видно даже за пределами функции, и программа печатает 5.

Глобальные переменные

Глобальная переменная — это переменная, объявленная на верхнем уровне файла, вне функций и блоков. Её видят все функции файла, и любая из них может её изменить. Она существует, пока работает программа, и хранит значение между вызовами функций.

Если значение меняют несколько функций, по коду трудно понять, какая из них записала его последней. С вещью на лестнице то же самое: она переехала, но кто её трогал, неизвестно.

Поэтому данные передают через параметры и return, а на верхнем уровне держат константы: ни одна функция не может присвоить им новое значение.

Присваивание имени, которое нигде не объявлено, JavaScript по умолчанию тоже не считает ошибкой. Он создаёт глобальную переменную с этим именем, даже если строка стоит внутри функции. Так опечатка totl превратилась в новую переменную, которую видит весь файл.

Строгий режим

Строка "use strict"; в самом начале файла включает строгий режим. В нашей картинке это вахтёр у входа в подъезд: он не пропускает на лестницу вещь, которую никто не записал.

В строгом режиме присваивание необъявленному имени останавливает программу с той же ошибкой ReferenceError, что и чтение такого имени:

JavaScript
"use strict";

let total = 0;

function add(n) {
    totl = total + n; // ✗
}

add(5);
TEXT
ReferenceError: totl is not defined

Так пишут Node.js и Chrome, а Firefox пишет ReferenceError: assignment to undeclared variable totl. Теперь опечатка видна при первом же вызове add.

Строгий режим превращает в ошибки и другие промахи, которые без него проходят молча. Например, функция с двумя одинаковыми параметрами, function f(a, a), в строгом режиме становится синтаксической ошибкой.

Где действует строка "use strict";, зависит от того, где она стоит:

  • первой строкой файла она включает режим для всего файла;
  • первой строкой тела функции она включает режим только внутри этой функции;
  • без неё файл выполняется в обычном, нестрогом режиме.

На собеседовании часто спрашивают: «Что делает "use strict"?» Начните с главного: в строгом режиме присваивание необъявленному имени даёт ReferenceError, а не новую глобальную переменную.

Частая ошибка

"use strict" написали не в начале файла:

JavaScript
let count = 0;
"use strict"; // ✗
cuont = count + 1;
console.log(cuont); // 1

Строгий режим не включился, и опечатка снова создала глобальную переменную. Строка "use strict" работает, только когда стоит первой в файле или в теле функции. Ниже она становится обычной строкой, которая ничего не делает.

Здесь картинка с вахтёром перестаёт работать. Опоздавший вахтёр всё равно начал бы проверять, а опоздавшая строка не проверяет ничего. Перенесите её в самое начало файла.

Главное

  • Глобальная переменная объявлена на верхнем уровне файла: её видят и могут изменить все функции.
  • Без строгого режима присваивание необъявленному имени создаёт новую глобальную переменную.
  • "use strict"; первой строкой файла или функции превращает такое присваивание в ReferenceError.
  • Данные передают через параметры и return, а на верхнем уровне держат константы.

Подпишись, чтобы пройти курс

Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.

Войти другим способом