Strict Mode в ECMAScript. Полный справочник08.02.2024 10:15
По поводу строго режима существует множество информации. Но, к сожалению, очень мало статьей, покрывающих весь спектр особенностей строго режима. Поэтому, я решил составить свой справочник всех ограничений, исключений и отличий в исполнении «строгого» кода от «не строгого», в полном соответствии со спецификацией ECMA-262.
Что такое строгий режим
В спецификации ECMA-262 существует два понятия: «нестрогий режим» (non-strict mode) и «строгий режим» (strict mode). Каждая синтаксическая единица ECMAScript всегда исполняется с использованием синтаксиса и семантики того или другого режима. В отличие от нестрого, строгий режим исполнения накладывает ряд синтаксических ограничений, и, даже может исполняться иначе.
Какой код исполняется в строгом режиме, а какой в нестрогом
Для начала, стоит сказать, что, будучи примененным к данной синтаксической единице, отменить строгий режим в процессе исполнения для неё уже нельзя. Спецификацией не предусмотрено никаких директив для этого.
В строгом режим работает весь модульный код Module code и все части классового кода ClassDeclaration. Нет никакого способа отключить строгий режим в таком коде.
Весь остальной код, по умолчанию работает в нестрогом режиме, но его можно активировать посредством директивы «use strict» в Directive Prologue (строка, идущая до каких-либо других деклараций).
Ниже приведены возможные варианты включения строго режима в разных типах кода.
"use strict"
// Global code теперь работает в строгом режиме
eval(`"use strict"
// Eval code теперь работает в строгом режиме
`);
function foo() {
"use strict"
// Function code теперь работает в строгом режиме, а сама функция теперь называется строгой
}
new Function('a', 'b', `
"use strict";
// При использовании конструктора функции, строгий режим можно включить
// в последнем аргументе конструктра, являющимся телом функции
return a + b;
`)
Так же, стоит учитывать, что код внутри строго режима будет распространять режим и на все вложенные синтаксические единицы.
"use strict"
eval(`
// Eval code работает в строгом режиме
`);
function foo() {
// как и Function code
function bar() {
// и вложенные функции тоже
}
}
Зарезервированные слова
Зарезервированными (reserved words) считаются слова, которые нельзя использовать в качестве идентификатора. Не стоит путать зарезервированные слова с ключевыми (keywords). Многие из ключевых слов являются зарезервированными, но не все. Также, есть слова, которые являются зарезервированными только в конкретном контексте (например, await является зарезервированным только внутри асинхронной функции или модуля).
Конкретно в strict mode зарезервированными считаются следующие слова:
implements, interface, let, package, private, protected, public, static, yield
Это значит, что их нельзя использовать в качестве индентификаторов
"use strict"
let implements = "";
// Uncaught SyntaxError: Unexpected strict mode reserved word
Восьмеричный литерал
В строгом режиме его использование запрещено. На всякий случай напомню, восьмеричный литерал начинается с символа 0 (можно несколько) и далее цифры 0, 1, 2, 3, 4, 5, 6, 7
"use strict"
01
// Uncaught SyntaxError: Octal literals are not allowed in strict mode.
Объявление переменных и свойства объекта
В нестрогом режиме, подобная конструкция приводит к тому, что в глобальном контексте объявляется переменная, которой присваивается значение
a = "a"
// Window {
// ...
// a: "a"
// }
В строгом режиме такой код запрещен
"use strict"
a = "a";
// Uncaught ReferenceError: a is not defined
Также, в строгом режиме учитывается атрибут { [[Writable]]: false } свойств объекта
"use strict"
const object = {};
Object.defineProperty(object, "a", {
value: "a",
writable: false,
});
object.a = "b";
// Uncaught TypeError: Cannot assign to read only property 'a' of object '#