Волшебная строчка "use strict"
в коде программы на JavaScript
включает строгий режим. (Или не делает ничего, в реализациях
до пятой ECMAScript). Действие этой директивы распространяется на
скоуп, в котором она указана.
// file: ok.js
"use strict"; // действует на весь файл
alert("ok");
(function() {
"use strict"; // действует только в пределах функции
alert("ok");
}());
Посмотреть, на сколько ваш браузер поддерживает "strict mode" вы можете, например, тут. Перечислю основные и важнейшие особенности режим, которые сэкономят вам часы разработки.
Это спасает в случае опечаток и случайных ошибок.
Код
(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 этого не происходит.
Это один из подводных камней: ошибок и предупреждений вы не получите, а код станет работать иначе.
Будьте осторожны.