что такое «строгий режим» и как он используется?

134

Я просматривал ссылку на JavaScript в Mozilla Developer Network и наткнулся на то, что называется "strict mode". Я перечитал его, и у меня возникли проблемы с пониманием того, что он делает. Может ли кто-нибудь кратко объяснить (в общем), какова его цель и как она полезна?

nkcmr
источник
2
Связанный: stackoverflow.com/q/1335851/1461424
сампатрис

Ответы:

149

Его основная цель - сделать больше проверок.

Просто добавьте "use strict";вверху вашего кода, прежде чем что-либо еще.

Например, blah = 33;допустим JavaScript. Это означает, что вы создаете полностью глобальную переменную blah.

Но в строгом режиме это ошибка, потому что вы не использовали ключевое слово «var» для объявления переменной.

В большинстве случаев вы не хотите создавать глобальные переменные в середине произвольной области видимости, поэтому большую часть времени blah = 33пишется, что это ошибка, и программист на самом деле не хотел, чтобы она была глобальной переменной, они имели в виду написать var blah = 33.

Это также запрещает многие вещи, которые технически обоснованно делать. NaN = "lol"не выдает ошибку. Это также не меняет значение NaN. использование строгого this (и подобных странных операторов) приводит к ошибкам. Большинство людей ценят это, потому что нет причин писать NaN = "lol", поэтому, скорее всего, была опечатка.

Узнайте больше на странице MDN о строгом режиме

Саймон Саррис
источник
4
это точный дубликат документации на MDN
nkcmr
23
Что вы не понимаете о его полезности тогда? Он направлен на то, чтобы помочь развитию, отлавливая вещи, которые являются допустимыми, но наиболее вероятными ошибками.
Саймон Саррис
34

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

Итак, такие вещи

function Obj() {
   this.a = 12;
   this.b = "a";
   this.privilegedMethod = function () {
      this.a++;
      privateMethod();
   };

   function privateMethod() {
     this.b = "foo";
   }
}

вызовет ошибку при privateMethodвызове (поскольку вы не можете добавить свойство к undefined), вместо того, чтобы бесполезно добавлять bсвойство к глобальному объекту.

Адам Рэкис
источник
4
да нужно добавить privateMethod.bind(this)();и позвонить сnew jsbin.com
hlcs
Самые важные ограничения в строгом режиме: docs.microsoft.com/en-us/scripting/javascript/advanced/…
Кришна Мохан,
21

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

Harmony , который, как мы надеемся, станет следующей основной версией EcmaScript, будет построен на основе строгой ES5.

Гармония основана на строгом режиме ES5, чтобы избежать слишком большого количества режимов.

Некоторые другие языковые эксперименты также зависят от строгого режима. SES зависит от анализируемости строгого режима ES5.

SES (Secure ECMAScript) Эксперимент по проектированию

Разработайте язык программирования возможностей объекта, удалив или исправив функции в ES5 / Strict.

Должен быть прямой перевод с SES на ES5 / Strict.

Приложение C стандарта объясняет различия между строгим режимом и нормальным режимом.

Строгое ограничение режима и исключения

  • Идентификаторы «Implements», «interface», «let», «package», «private», «protected», «public», «static» и «yield» классифицируются как токены FutureReservedWord в коде строгого режима. (7.6.12 [?]).
  • Соответствующая реализация при обработке кода строгого режима может не расширять синтаксис NumericLiteral (7.8.3) для включения OctalIntegerLiteral, как описано в B.1.1.
  • Соответствующая реализация при обработке кода строгого режима (см. 10.1.1) может не расширять синтаксис EscapeSequence, чтобы включить OctalEscapeSequence, как описано в B.1.2.
  • Присвоение необъявленного идентификатора или иным неразрешимым ссылкам не создает свойства в глобальном объекте. Когда в коде строгого режима происходит простое присвоение, его LeftHandSide не должен преобразовываться в неразрешимую ссылку. Если это происходит, генерируется исключение ReferenceError (8.7.2). LeftHandSide также не может быть ссылкой на свойство данных со значением атрибута {[[Writable]]: false}, на свойство метода доступа со значением атрибута {[[Set]]: undefined} или на несуществующее свойство объекта, чье внутреннее свойство [[Extensible]] имеет значение false. В этих случаях выдается исключение TypeError (11.13.1).
  • Идентификатор eval или аргументы могут не отображаться как выражение LeftHandSideExpress оператора присваивания (11.13) или выражения PostfixExpression (11.3) или как выражение UnaryExpression, оперируемое оператором увеличения префикса (11.4.4) или оператора уменьшения префикса (11.4.5) , Объекты аргументов для функций строгого режима определяют неконфигурируемые свойства средства доступа с именами «вызывающий» и «вызываемый», которые генерируют исключение TypeError при доступе (10.6).
  • Объекты аргументов для функций строгого режима динамически не разделяют значения своих индексированных свойств массива с соответствующими привязками формальных параметров своих функций. (10.6). Для функций строгого режима, если создается объект аргументов, привязка аргументов локального идентификатора к объекту аргументов является неизменной и, следовательно, не может быть целью выражения присваивания. (10.5).
  • Это ошибка SyntaxError, если код строгого режима содержит ObjectLiteral с более чем одним определением какого-либо свойства данных (11.1.5). Это SyntaxError, если Идентификатор "eval" или Идентификатор "arguments" встречается как Идентификатор в PropertySetParameterList PropertyAssignment, который содержится в строгом коде, или если его FunctionBody является строгим кодом (11.1.5).
  • Eval-код строгого режима не может создавать экземпляры переменных или функций в переменной среде вызывающей стороны для eval. Вместо этого создается новая переменная среда, и эта среда используется для создания экземпляров привязки объявлений для кода eval (10.4.2).
  • Если это вычисляется в коде строгого режима, то это значение не приводится к объекту. Значение null или undefined не преобразуется в глобальный объект, а примитивные значения не преобразуются в объекты-оболочки. Значение this, переданное через вызов функции (включая вызовы, выполненные с использованием Function.prototype.apply и Function.prototype.call), не приводит к принудительной передаче переданного значения this объекту (10.4.3, 11.1.1, 15.3.4.3, 15.3. 4.4).
  • Когда оператор удаления встречается в коде строгого режима, выдается SyntaxError, если его UnaryExpression является прямой ссылкой на переменную, аргумент функции или имя функции (11.4.1).
  • Когда в коде строгого режима возникает оператор удаления, выдается ошибка TypeError, если удаляемое свойство имеет атрибут {[[Configurable]]: false} (11.4.1). Это SyntaxError, если VariableDeclaration или VariableDeclarationNoIn встречаются в строгом коде, а его Идентификатор равен eval или arguments (12.2.1).
  • Код строгого режима может не включать WithStatement. Вхождение WithStatement в таком контексте является ошибкой SyntaxError (12.10).
  • Это SyntaxError, если TryStatement с Catch происходит в строгом коде и Идентификатор производства Catch равен eval или arguments (12.14.1)
  • Это ошибка SyntaxError, если идентификатор eval или аргументы появляются в FormalParameterList строгого режима FunctionDeclaration или FunctionExpression (13.1)
  • Функция строгого режима может не иметь двух или более формальных параметров с одинаковыми именами. Попытка создать такую ​​функцию с помощью конструктора FunctionDeclaration, FunctionExpression или Function представляет собой SyntaxError (13.1, 15.3.2).
  • Реализация не может расширять, помимо того, что определено в этой спецификации, значения в функциях строгого режима свойств, называемых caller, или аргументов экземпляров функций. Код ECMAScript не может создавать или изменять свойства с этими именами на объектах функций, которые соответствуют функциям строгого режима (10.6, 13.2, 15.3.4.5.3).
  • Это ошибка SyntaxError для использования в коде строгого режима идентификаторов eval или аргументов в качестве идентификатора FunctionDeclaration или FunctionExpression или в качестве формального имени параметра (13.1). Попытка динамически определить такую ​​функцию строгого режима с помощью конструктора Function (15.3.2) вызовет исключение SyntaxError.
Майк Самуэль
источник
6

ECMAScript 5 ввел понятие строгого режима .

Вызов строгого режима в коде

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

Весь сценарий:

Допустим, мы создаем app.js, поэтому добавление сценария использования первого оператора приведет к строгому режиму для всего кода.

// app.js whole script in strict mode syntax
use strict”;
// Now you can start writing your code 

Строгий режим для функции:

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

function yourFunc(){
 "use strict";

 // Your function code logic
}

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

Для экземпляра: код с использованием строгого режима

введите описание изображения здесь

В приведенном выше примере кода без использования строгого режима в коде ошибка не выдаст. Поскольку мы обращаемся к переменной, xне объявляя ее. Поэтому в строгом режиме доступа к необъявленной переменной выдается ошибка.

Теперь давайте попробуем получить доступ к переменной x, не объявляя ее без строгого режима.

(function(){
    x = 3;
})();

// Will not throw an error

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

  • Устраните скрытые ошибки JavaScript, выбрасывая ошибки.
  • Исправляет ошибку, которая затрудняет оптимизацию движка JavaScript.
  • Заставьте код работать быстрее, чем идентичный код, который не находится в строгом режиме
  • Запрещает некоторый синтаксис, который может быть определен в будущей версии ECMAScript.
Нишант Кумар
источник
5

Строгий режим вносит несколько изменений в обычную семантику JavaScript.

  • строгий режим устраняет некоторые тихие ошибки JavaScript, изменяя их на ошибки.

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

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

Ренганатан М.Г.
источник
1

ECMAScript5вводит некоторые новые объекты и свойства, а также так называемые "strict mode".

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

"use strict";
Вахид Халладжи
источник
1

2017, и я наконец нашел документацию:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

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


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

Тилак Мэдди
источник
0

Вопрос:
Ниже приведена проблема, с которой я столкнулся, я следовал учебному пособию, и в итоге я попытался скомпилировать следующий scssфайл и сгенерировать из него код CSS,

.fatty{
  width: percentage(6/7);
}

используя следующую gulpfile.jsзадачу:

var gulp = require('gulp');
var sass = require('gulp-sass');

gulp.task('sass', function () {
    return gulp.src('app/scss/styles.scss')
        .pipe(sass())
        .pipe(gulp.dest('app/css'))
});

Итак, ошибка, которую я получаю, заключается в следующем:

~/htdocs/Learning/gulp1/node_modules/gulp-sass/index.js:66
    let sassMap;
    ^^^

SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:373:25)
// stacktrace here...

Решение:
Итак, он показывает мне index.jsфайл, который находится внутри моего модуля gulp-sass (который в основном заблокирован и не должен редактироваться). Но если я решительно добавлю "use_strict"верхнюю часть этого index.jsфайла, моя задача будет выполнена гладко.

Я был беспомощен, поэтому я продолжаю использовать это как решение! Но затем, пройдя некоторые другие вопросы и ответы по SO , я увидел следующий ответ :

sudo npm install -g n
sudo n stable

и вскоре я обновил свои NodeJ (до Version10.x), а затем перестроил Gulp, выполнив следующие команды, как дал мне указание терминала:

npm rebuild node-sass --force

И все в порядке. Так вот как это было решено. Я отменил изменения, которые я сделал для index.jsфайла модуля gulp. И теперь все идет гладко.

Надеюсь, что этот ответ будет полезен для кого-то там!

Рандика Вишман
источник