Глобальные переменные и строгий режим
Квартира с комнатами стоит в многоквартирном доме. Вещь, оставленную на лестнице в подъезде, видят жильцы всех квартир, и любой из них может её переставить. В программе такой лестнице соответствует верхний уровень файла, вне всех функций и блоков.
Опечатка в имени переменной не всегда останавливает программу. Здесь в функции add вместо total написано totl, но ошибки нет:
let total = 0;
function add(n) {
totl = total + n;
}
add(5);
console.log(total); // 0
console.log(totl); // 5Давайте разберём, что произошло:
add(5)выполняет строкуtotl = total + n, и справа от=получается5.- Имя
totlнигде не объявлено, но программа не останавливается: появляется новая переменнаяtotlсо значением5. totalникто не менял, и программа печатает0.- Новую
totlвидно даже за пределами функции, и программа печатает5.
Глобальные переменные
Глобальная переменная — это переменная, объявленная на верхнем уровне файла, вне функций и блоков. Её видят все функции файла, и любая из них может её изменить. Она существует, пока работает программа, и хранит значение между вызовами функций.
Если значение меняют несколько функций, по коду трудно понять, какая из них записала его последней. С вещью на лестнице то же самое: она переехала, но кто её трогал, неизвестно.
Поэтому данные передают через параметры и return, а на верхнем уровне держат константы: ни одна функция не может присвоить им новое значение.
Присваивание имени, которое нигде не объявлено, JavaScript по умолчанию тоже не считает ошибкой. Он создаёт глобальную переменную с этим именем, даже если строка стоит внутри функции. Так опечатка totl превратилась в новую переменную, которую видит весь файл.
Строгий режим
Строка "use strict"; в самом начале файла включает строгий режим. В нашей картинке это вахтёр у входа в подъезд: он не пропускает на лестницу вещь, которую никто не записал.
В строгом режиме присваивание необъявленному имени останавливает программу с той же ошибкой ReferenceError, что и чтение такого имени:
"use strict";
let total = 0;
function add(n) {
totl = total + n; // ✗
}
add(5);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" написали не в начале файла:
let count = 0;
"use strict"; // ✗
cuont = count + 1;
console.log(cuont); // 1Строгий режим не включился, и опечатка снова создала глобальную переменную. Строка "use strict" работает, только когда стоит первой в файле или в теле функции. Ниже она становится обычной строкой, которая ничего не делает.
Здесь картинка с вахтёром перестаёт работать. Опоздавший вахтёр всё равно начал бы проверять, а опоздавшая строка не проверяет ничего. Перенесите её в самое начало файла.
Главное
- Глобальная переменная объявлена на верхнем уровне файла: её видят и могут изменить все функции.
- Без строгого режима присваивание необъявленному имени создаёт новую глобальную переменную.
"use strict";первой строкой файла или функции превращает такое присваивание вReferenceError.- Данные передают через параметры и
return, а на верхнем уровне держат константы.
Подпишись, чтобы пройти курс
Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.