Понимание строгого режима Javascript и его преимуществ

JavaScript остается одним из наиболее широко используемых языков программирования в Интернете, обеспечивая все, от простых интерактивных форм до сложных одностраничных приложений. По мере роста проектов и увеличения числа членов команды, необходимость в надежном, предсказуемом коде становится первостепенной. Именно здесь в игру вступает строгий режим JavaScript - функция, введенная в ECMAScript 5. Строгий режим позволяет разработчикам выбирать ограниченный вариант языка, помогая улавливать распространенные ошибки, предотвращать опасные действия и в конечном итоге производить более безопасный и поддерживаемый код. Применяя более строгий анализ и обработку ошибок, строгий режим превращает ранее молчаливые сбои в явные исключения, делая отладку проще и поощряя лучшие привычки кодирования. В этом всеобъемлющем руководстве мы рассмотрим, что такое строгий режим, как его включить, его многочисленные преимущества и практические примеры для иллюстрации его влияния.

Что такое строгий режим?

Строгий режим — это способ выбрать более дисциплинированное подмножество JavaScript. При включении движок JavaScript запускает код под набором ограничений, которые устраняют некоторые из более подверженных ошибкам особенностей языка. Идея строгого режима заключается в том, чтобы предоставить разработчикам более раннюю обратную связь о потенциальных проблемах. Например, в нестрогом режиме (часто называемом «небрежным режимом»), присваивая значение незаявленной переменной, молча создает глобальную переменную. В строгом режиме это бросает . Аналогично, строгий режим запрещает использование определенных устаревших или проблемных конструкций, таких как утверждение и восьмизначные числовые буквы. Цель состоит в том, чтобы сделать JavaScript более надежным, безопасным и последовательным, особенно в больших кодовых базах.

ECMAScript 5 ввел строгий режим в 2009 году как способ развития языка без нарушения обратной совместимости. Разработчики могли бы выбрать новое, более строгое поведение, просто добавив в верхней части сценария или функции. С тех пор строгий режим стал рекомендуемой практикой во многих руководствах по стилю и автоматически применяется в современных конструкциях JavaScript, таких как модули ES (импорт / экспорт) и классы. Понимание того, как работает строгий режим, имеет важное значение для любого профессионального разработчика JavaScript.

Как включить строгий режим

Включение строгого режима просто: вы вставляете строку буквальную (или ) в начале сценария или функции. Эта директива не является утверждением, а прагмой, которая говорит движку анализировать последующий код в строгом режиме. Она может применяться в двух областях: глобально (для всего сценария) или локально (для одной функции). Кроме того, модули и классы ES автоматически находятся в строгом режиме, поэтому не требуется никакой явной директивы.

Строгий режим Script-Level

Чтобы включить строгий режим для всего файла JavaScript или встроенного блока , поместите в качестве самой первой строки сценария (до любых других утверждений).

// script.js
'use strict';

var x = 10;
console.log(x); // works normally

// Attempting to use undeclared variables throws an error
y = 20; // ReferenceError: y is not defined

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

Функциональный уровень строгий режим

Вы также можете включить строгий режим внутри определенной функции, оставив остальную часть сценария в небрежном режиме. Это полезно при постепенной миграции кодовой базы или когда вы хотите строгую проверку только для определенных функций. Поместите в верхней части корпуса функции, перед любыми другими утверждениями:

function strictFunction() {
 'use strict';
 // Inside this function, strict mode applies
 var a = 1;
 b = 2; // ReferenceError: b is not defined
}

function sloppyFunction() {
 // Outside strictFunction, sloppy mode still applies
 c = 3; // creates global variable c
}

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

Модули и классы

С появлением ES6 (ES2015) в JavaScript были введены модули и классы. Оба автоматически находятся в строгом режиме по умолчанию. Поэтому, если вы пишете свой код с использованием синтаксиса / или определяете , вам не нужно добавлять — строгий режим обеспечивается автоматически. Например:

// module.js (no 'use strict' needed)
export function add(a, b) {
 // strict mode is active here
 return a + b;
}

// class definition (strict mode active)
class MyClass {
 constructor(value) {
 this.value = value;
 }
}

Это автоматическое обеспечение делает код в модулях и классах по своей сути более безопасным и легким для рассуждения.

Основные преимущества использования строгого режима

Строгий режим предлагает множество преимуществ, которые непосредственно улучшают качество кода, безопасность и опыт разработчиков. Давайте рассмотрим каждое преимущество подробно.

Предотвращает случайные глобальные переменные

В нестрогом режиме присвоение значения незаявленной переменной автоматически создает свойство на глобальном объекте (] в браузерах, в Node.js. Это может легко произойти из-за типографских ошибок или забытых деклараций, загрязняя глобальное пространство имен и вызывая тонкие ошибки. Строгий режим делает это невозможным, бросая . Например:

// Non-strict: silently creates global variable
function setup() {
 developer = "Alice"; // accidentally global
}

// Strict: throws ReferenceError
function setup() {
 'use strict';
 developer = "Alice"; // ReferenceError: developer is not defined
}

Это принуждение заставляет разработчиков явно объявлять переменные , или , уменьшая связанные с областью ошибки.

Устранение молчаливых ошибок

JavaScript часто прощает, когда операции не выполняются бесшумно. Например, назначение свойства только для чтения (например, или замороженный объект) просто ничего не делает в небрежном режиме. В строгом режиме такие назначения бросают . Аналогично, попытки удалить неудаляемые свойства (например, ) бросают ошибку вместо молчаливого возврата . Это делает отладку намного проще, потому что разработчик получает немедленную обратную связь.

// Non-strict: assignment silently fails
var obj = Object.freeze({name: "Bob"});
obj.name = "Charlie"; // silently ignored

// Strict: TypeError thrown
'use strict';
var obj = Object.freeze({name: "Bob"});
obj.name = "Charlie"; // TypeError: Cannot assign to read-only property 'name'

Предотвращает дублирование названий параметров

В нестрогом режиме функции могут иметь имена дублирующих параметров, что может привести к запутанному поведению (последний дублирующий перезаписывает более ранние). Строгий режим запрещает это, бросая в разбор времени. Например:

// Non-strict: allowed
function sum(a, a, c) {
 return a + a + c; // a equals the second argument passed
}

// Strict: SyntaxError
'use strict';
function sum(a, a, c) { // SyntaxError: Duplicate parameter name not allowed in strict mode
 return a + a + c;
}

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

Ограничить заявление

Заявление уже давно считается вредным, поскольку оно создает двусмысленность в отношении переменного разрешения и ухудшает производительность. Строгий режим полностью запрещает высказывание , бросая во время компиляции. Это удаление побуждает разработчиков использовать более предсказуемые шаблоны, такие как деструктивный или явный доступ к собственности.

Безопаснее

В нестрогом режиме может вводить новые переменные в окружающий объем, что приводит к непредсказуемым побочным эффектам. Строгий режим изменяет поведение , так что он создает переменные только в самом коде Eval — они не просачиваются в окружающий контекст. Это облегчает анализ кода и предотвращает случайное загрязнение области.

// Non-strict: eval creates variable in outer scope
var x = 1;
eval("var x = 2;");
console.log(x); // 2

// Strict: eval has its own scope
'use strict';
var x = 1;
eval("var x = 2;");
console.log(x); // 1

Запрет на октябрьские числовые буквы

Исторически JavaScript интерпретировал числа с ведущим нулем (например, ]) как восьмичные (база 8). Такое поведение часто вызывало путаницу и ошибки, особенно при работе со строками, такими как «010», которые разбираются как числа. Строгий режим запрещает восьмизначные числовые буквы (за исключением префикса ES6+ ) и бросает . Это устраняет целый класс тонких ошибок.

// Non-strict: 010 means octal 8
console.log(010); // 8

// Strict: SyntaxError
'use strict';
console.log(010); // SyntaxError: Octal literals are not allowed in strict mode

Запрещается удалять простые переменные

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

// Non-strict: attempt silently fails
var a = 1;
delete a; // false; a still exists

// Strict: SyntaxError
'use strict';
var a = 1;
delete a; // SyntaxError: Delete of an unqualified identifier in strict mode

Дополнительная безопасность и улучшение производительности

Помимо конкретных ограничений, строгий режим позволяет JavaScript-движкам выполнять определенные оптимизации, которые в противном случае невозможны. Поскольку строгий режим устраняет некоторые динамические поведения (например, заявление и неявные глобали), движок может лучше предсказать, как будут использоваться переменные, что приводит к более быстрому выполнению в некоторых случаях. Кроме того, строгий режим отключает свойство и свойство функций , которые исторически использовались для самоанализа, но также создавали риски безопасности, позволяя доступ к стеку вызовов. Это ограничение усиливает инкапсуляцию и предотвращает определенные типы атак.

Примеры строгого режима в действии

Чтобы укрепить понимание, давайте пройдемся по ряду примеров, которые контрастируют небрежный режим со строгим режимом. Они демонстрируют немедленную обратную связь, которую обеспечивает строгий режим.

Пример 1: Необъявленное переменное назначение

// sloppy.js
function userInfo() {
 name = "John"; // silently creates global 'name'
}
userInfo();
console.log(window.name); // "John" (in browsers)

// strict.js
'use strict';
function userInfo() {
 name = "John"; // ReferenceError: name is not defined
}
userInfo();

Без строгого режима простая опечатка вроде вместо может загрязнить глобальный масштаб. При строгом режиме ошибка фиксируется мгновенно.

Пример 2: Присвоение глобальной собственности, доступной только для чтения

// sloppy mode
undefined = 5; // silently fails (undefined remains undefined)
NaN = 6; // silently fails
console.log(undefined, NaN); // undefined, NaN

// strict mode
'use strict';
undefined = 5; // TypeError: Cannot assign to read-only property 'undefined' of object '#<Window>'
NaN = 6; // TypeError

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

Пример 3: Дублированные названия объектов недвижимости

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

// sloppy: works, last value wins
var config = {
 host: "example.com",
 host: "backup.com" // no error
};
console.log(config.host); // "backup.com"

// strict: SyntaxError
'use strict';
var config = {
 host: "example.com",
 host: "backup.com" // SyntaxError: Duplicate data property in object literal not allowed in strict mode
};

Общие подводные камни и миграция в строгом режиме

Хотя строгий режим приносит много преимуществ, миграция большой существующей кодовой базы может представлять проблемы. Некоторые старые шаблоны, которые считались приемлемыми в ES3/5, теперь могут потерпеть неудачу. Наиболее распространенные проблемы включают:

Процесс миграции часто инкрементален. Вы можете включить строгий режим работы по функциям, используя прагму внутри функций, тщательно протестировать, а затем включить его глобально, как только вы уверены. Инструменты, такие как ESLint с его правилом , могут помочь автоматически идентифицировать нарушения. Кроме того, использование модулей или классов ES автоматически дает вам строгое поведение режима, поэтому миграция в современный синтаксис является естественным путем к более строгому коду.

Также стоит отметить, что строгий режим не является убийцей производительности. На самом деле, как уже упоминалось, некоторые двигатели могут лучше оптимизировать строгий код режима. Начальная проверка времени выполнения директивы ничтожна, а общая ясность кода и безопасность намного перевешивают любые предельные затраты.

Выводы и лучшие практики

Строгий режим JavaScript является мощным инструментом для написания более надежного, поддерживающего и безопасного кода. Выбрав этот ограниченный подмножество языка, разработчики получают раннее обнаружение распространенных ошибок, избегают опасных конструкций и извлекают выгоду из лучшей производительности во многих случаях. Включение строгого режима так же просто, как добавление в начале сценария или функции, и он автоматически активен в модулях и классах ES. Преимущества - предотвращение случайных глобалов, устранение немых ошибок, ограничение вредных функций, таких как и - непосредственно переводят в меньшее количество ошибок и более быстрые циклы отладки.

Для любого проекта, будь то новый или устаревший, принятие строгого режима должно считаться лучшей практикой. Начните с использования linter для выявления нарушений, постепенно исправляйте их и часто тестируйте. Современные инструменты и фреймворки JavaScript часто предполагают строгий режим (или обеспечивают его соблюдение), поэтому согласование с этим соглашением обеспечивает совместимость и согласованность. Обнимая строгий режим, вы присоединяетесь к более широкому сообществу JavaScript в определении приоритетов качества и безопасности кода.

Чтобы погрузиться глубже, обратитесь к документации MDN о строгом режиме для полного списка ограничений и примеров. Для исторического контекста спецификация ECMAScript объясняет формальные правила. Кроме того, строгое правило ESLint обеспечивает автоматизированный способ обеспечения последовательного использования в вашем проекте.