Что такое "use strict"?
Для того, чтобы перевести код в режим полного соответствия современному стандарту, нужно указать специальную директиву use strict.
Директива use strict; говорит о том, что код должен быть выполнен в «строгом режиме». Один из плюсов данного режима — это то, что он предотвращает использование необъявленных переменных. Наиболее старые версии JavaScript будут игнорировать данную директиву.
Директива выглядит как строка "use strict"; или 'use strict'; и ставится в начале скрипта.
// Пример "строгого режима"
"use strict";
catchThemAll();
function catchThemAll() {
x = 3.14; // На этом моменте будет ошибка
return x * x;
}
Не допускает дублирование ключей в объекте
Это спасает в случае опечаток и случайных ошибок.
Код
(function() {
"use strict";
var x = {
a: 1,
b: 2,
a: 3
}
}());
Приведёт к возникновению ошибки
Uncaught SyntaxError: Duplicate data property in object literal not allowed in strict mode
Требует всегда явного объявления переменных черезvar
(function() {
"use strict";
var a = 1; // правильно
x = 2; // ошибка: нет var
}());
Uncaught ReferenceError: x is not defined
Это прекрасная возможность! Она спасает от ошибок, которые очень трудно находить. Когда у вас две совершенно независимые функции оказались завязаны через переменную, которая неожиданно оказалась глобальной.
Но с этой возможностью надо быть осторожней, она хорошо работает, только если весь скрипт находится в режиме strict. В следующем примере strict mode бессильна:
// file: ok.js
// на уровне файла strict mode не включена
x = 0; // глобальная переменная (вернее, при таком раскладе, свойство window)
(function() {
"use strict";
x = 2; // var нет, но и ошибки не возникнет, так как глобальная x существует
}());
Это может привести к неприятным последствиям. Вот такой, простой и естественный код приведёт к фатальному зацикливанию и впадению браузера в ступор.
function f() {
"use strict";
for (i = 0; i < 3; ++i) {
console.log(i);
}
}
for (i = 0; i < 10; ++i) {
console.log(i);
f();
}
Дело в том, что вызов функцииf()
каждый раз будет устанавливать значение глобальной переменнойi
(а она тут получилась глобальной) в 3. И цикл до 10 никогда не закончится.
Strict mode здесь, к сожаления, не поможет. Но если бы"use strict"
было бы включено глобально на весь файл, то браузер сразу же сообщил бы вам о подозрительном коде.
Uncaught ReferenceError: i is not defined
Запрещаются дублирования аргументов
Не допускаются опечатки типа:
function sum(a, a) {...
Uncaught SyntaxError: Strict mode function may not have duplicate parameter names
Такая конструкция может возникнуть только в результате опечатки. Смысла в ней нет, а ведёт себя такой код не хорошо. Вызовы и результат внутри функции:
sum(); // a === undefined
sum(1); // a === undefined
sum(1, 2); // a === 2
Скорее всего, это не то, чего ожидает разработчик.
Происходит заморозка arguments
Тут можно потерять обратную совместимость. Массив arguments
в strict mode начинает вести себя подобно обычным массивам (хотя, он не становится от этого обычным массивом). Результат проще показать на примере:
function a(x) {
arguments[0] = 2;
console.log(x); // напечатает 2
}
function b(x) {
"use strict";
arguments[0] = 2;
console.log(x); // напечатает 1
}
a(1);
b(1);
То есть, в обычном режиме изменение arguments приводит к изменению соответствующих переменных, а в strict mode этого не происходит.
Это один из подводных камней: ошибок и предупреждений вы не получите, а код станет работать иначе.
Будьте осторожны.