Что делает «использование строгих» в JavaScript, и каковы причины этого?



Answers

Это новая функция ECMAScript 5. Джон Ресиг написал хорошее резюме .

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

"use strict";

Включение этого кода теперь не должно вызывать проблем с текущими браузерами, поскольку это всего лишь строка. Это может вызвать проблемы с вашим кодом в будущем, если ваш код нарушает прагму. Например, если у вас в настоящее время есть foo = "bar" не определяя сначала foo , ваш код начнет сбой ... что, на мой взгляд, хорошо.

Question

Недавно я запустил некоторый код своего кода JavaScript через JSLint от Crockford, и он дал следующую ошибку:

Проблема в строке 1 символ 1: Отсутствует инструкция «use strict».

Выполняя некоторые поиски, я понял, что некоторые люди добавляют "use strict"; в свой код JavaScript. Как только я добавил заявление, ошибка перестала появляться. К сожалению, Google не раскрыл большую часть истории этого оператора строки. Конечно, это должно быть связано с тем, как JavaScript интерпретируется браузером, но я не знаю, каким будет эффект.

Итак, что такое "use strict"; все о том, что это подразумевает, и все еще актуально?

Любой из текущих браузеров реагирует на "use strict"; строка или это для будущего использования?




Normally java script does not follow strict rules hence increasing chances of errors. After using "use strict" , the java script code should follow strict set of rules as like in other programming languages such as use of terminators, declaration before initialization etc.

If "use strict" is used then the code should be written by following a strict set of rules hence decreasing the chances of errors and ambiguities.




There's a good talk by some people who were on the ECMAScript committee: Changes to JavaScript, Part 1: ECMAScript 5" about how incremental use of the "use strict" switch allows JavaScript implementers to clean up a lot of the dangerous features of JavaScript without suddenly breaking every website in the world.

Of course it also talks about just what a lot of those misfeatures are (were) and how ECMAScript 5 fixes them.




Just wanted to add some more points.

The Reason to Use Strict Mode--->

  • Strict mode makes it easier to write "secure" JavaScript.

  • Strict mode changes previously accepted "bad syntax" into real
    ошибки.

  • As an example, in normal JavaScript, mistyping a variable name
    creates a new global variable.

  • In strict mode, this will throw an error, making it impossible to accidentally create a global variable.

  • In strict mode, any assignment to a non-writable property, a
    getter-only property, a non-existing property, a non-existing
    variable, or a non-existing object, will throw an error.

The things that will throw errors in Strict Mode Using a variable, without declaring it, is not allowed:

"use strict";
 x = 3.14;                // This will cause an error

Objects are variables too.

Using an object, without declaring it, is not allowed:

  "use strict";
  x = {p1:10, p2:20};      // This will cause an error

Deleting a variable (or object) is not allowed.

  "use strict";
   var x = 3.14;
   delete x;                // This will cause an error

For security reasons, eval() is not allowed to create variables in the scope from which it was called:

"use strict";
 eval ("var x = 2");
 alert (x);               // This will cause an error

In function calls like f(), the this value was the global object. In strict mode, it is now undefined.

"use strict" is only recognized at the beginning of a script.




The main reasons why developers should use "use strict" are:

  1. Prevents accidental declaration of global variables.Using "use strict()" will make sure that variables are declared with var before use. Например:

    function useStrictDemo(){
     'use strict';
     //works fine
     var a = 'No Problem';
    
     //does not work fine and throws error
     k = "problem"
    
     //even this will throw error
     someObject = {'problem': 'lot of problem'};
    }
    
  2. NB: The "use strict" directive is only recognized at the beginning of a script or a function.
  3. The string "arguments" cannot be used as a variable:

    "use strict";
    var arguments = 3.14;    // This will cause an error
    
  4. Will restrict uses of keywords as variables. Trying to use them will throw errors.

In short will make your code less error prone and in turn will make you write good code.

To read more about it you can refer http://www.w3schools.com/js/js_strict.asp .




When adding "use strict"; , the following cases will throw a SyntaxError before the script is executing:

  • Paving the way for future ECMAScript versions , using one of the newly reserved keywords (in prevision for ECMAScript 6 ): implements , interface , let , package , private , protected , public , static , and yield .

  • Declaring function in blocks

    if(a<b){ function f(){} }
    
  • Octal syntax

    var n = 023;
    
  • this point to the global object.

     function f() {
          "use strict";
          this.a = 1;
     };
     f(); 
    
  • Declaring twice the same name for a property name in an object literal

     {a: 1, b: 3, a: 7} 
    

    This is no longer the case in ECMAScript 6 ( bug 1041128 ).

  • Declaring two function arguments with the same name function

    f(a, b, b){}
    
  • Setting a value to an undeclared variable

    function f(x){
       "use strict";
       var a = 12;
       b = a + x*35; // error!
    }
    f();
    
  • Using delete on a variable name delete myVariable;

  • Using eval or arguments as variable or function argument name

    "use strict";
    arguments++;
    var obj = { set p(arguments) { } };
    try { } catch (arguments) { }
    function arguments() { } 
    

Sources:




«Использовать строгий»; является страхованием, что программист не будет использовать свободные или плохие свойства JavaScript. Это руководство, точно так же, как правитель поможет вам сделать прямые линии. «Использовать Strict» поможет вам сделать «прямое кодирование».

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

Поверь мне. Накладные расходы незначительны по сравнению с плохо разработанным кодом. У Доктора Крокфорда, который уже несколько лет является старшим разработчиком JavaScript, есть очень интересный пост . Лично мне нравится постоянно возвращаться на его сайт, чтобы я не забыл свою хорошую практику.

Современная практика JavaScript всегда должна вызывать «Use Strict»; Прагма. Единственная причина, по которой ECMA Group сделала вариант «Строгий», - это разрешить доступ менее опытным кодовым машинам к JavaScript и дать время для адаптации к новым и более безопасным способам кодирования.




"use strict"; is the ECMA effort to make JavaScript a little bit more robust. It brings in JS an attempt to make it at least a little "strict" (other languages implement strict rules since the 90s). It actually "forces" JavaScript developers to follow some sort of coding best practices. Still, JavaScript is very fragile. There is no such thing as typed variables, typed methods, etc. I strongly recommend JavaScript developers to learn a more robust language such as Java or ActionScript3, and implement the same best practices in your JavaScript code, it will work better and be easier to debug.




Если вы используете браузер, выпущенный в прошлом году или около того, он, скорее всего, поддерживает режим JavaScript Strict. Только старые браузеры до того, как ECMAScript 5 стал текущим стандартом, не поддерживают его.

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




Note that use strict was introduced in EcmaScript 5 and was kept since then.

Below are the conditions to trigger strict mode in ES6 and ES7 :

  • Global code is strict mode code if it begins with a Directive Prologue that contains a Use Strict Directive (see 14.1.1).
  • Module code is always strict mode code.
  • All parts of a ClassDeclaration or a ClassExpression are strict mode code.
  • Eval code is strict mode code if it begins with a Directive Prologue that contains a Use Strict Directive or if the call to eval is a direct eval (see 12.3.4.1) that is contained in strict mode code.
  • Function code is strict mode code if the associated FunctionDeclaration, FunctionExpression, GeneratorDeclaration, GeneratorExpression, MethodDefinition, or ArrowFunction is contained in strict mode code or if the code that produces the value of the function's [[ECMAScriptCode]] internal slot begins with a Directive Prologue that contains a Use Strict Directive.
  • Function code that is supplied as the arguments to the built-in Function and Generator constructors is strict mode code if the last argument is a String that when processed is a FunctionBody that begins with a Directive Prologue that contains a Use Strict Directive.



Если люди обеспокоены use strict возможно, стоит проверить эту статью:

Поддержка ECMAScript 5 «Строгий режим» в браузерах. Что это значит?
NovoGeek.com - блог Кришны

В нем говорится о поддержке браузеров, но что еще более важно, как с этим справиться:

function isStrictMode(){
    return !this;
} 
/*
   returns false, since 'this' refers to global object and 
   '!this' becomes false
*/

function isStrictMode(){   
    "use strict";
    return !this;
} 
/* 
   returns true, since in strict mode the keyword 'this'
   does not refer to global object, unlike traditional JS. 
   So here, 'this' is 'undefined' and '!this' becomes true.
*/



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

Для получения дополнительной информации вы можете обратиться к документации MDN .

"use strict" директиву, введенную в ECMAScript 5.

Директивы похожи на утверждения, но разные.

  • use strict не содержит ключевых слов: директива - это простой оператор выражения, который состоит из специального строкового литерала (в одиночных или двойных кавычках). Механизмы JavaScript, которые не реализуют ECMAScript 5, просто видят выражение без побочных эффектов. Ожидается, что будущие версии стандартов ECMAScript внедрят use в качестве реального ключевого слова; Таким образом, кавычки станут устаревшими.
  • use strict может использоваться только в начале скрипта или функции, т. е. должно предшествовать любому другому (реальному) утверждению. Это не должно быть первой инструкцией в скрипте функции: ей могут предшествовать другие выражения операторов, которые состоят из строковых литералов (и реализации JavaScript могут рассматриваться как директивы, специфичные для реализации). Строковые литералы, которые следуют за первым реальным оператором (в скрипте или функции), являются простыми выражениями. Интерпретаторы не должны интерпретировать их как директивы, и они не имеют никакого эффекта.

use strict директива use strict указывает, что следующий код (в скрипте или функции) является строгим кодом. Код на самом высоком уровне скрипта (код, который не находится в функции) считается строгим кодом, когда скрипт содержит use strict директиву use strict . Содержание функции считается строгим кодом, когда сама функция определена в строгом коде или когда функция содержит use strict директиву use strict . Код, передаваемый методу eval() считается строгим кодом, когда eval() вызывается из строкового кода или содержит use strict директиву use strict .

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

  • Вы не можете использовать параметр with -statement в строгом режиме.
  • В строгом режиме все переменные должны быть объявлены: если вы присваиваете значение идентификатору, который не был объявлен как переменная, функция, параметр функции, параметр catch-clause или свойство глобального Object , тогда вы получите ReferenceError . В нормальном режиме идентификатор объявляется неявно как глобальная переменная (как свойство глобального Object )
  • В строгом режиме ключевое слово имеет значение undefined в функциях, которые вызывались как функции (а не как методы). (В нормальном режиме this всегда указывает на глобальный Object ). Это различие можно использовать для проверки, поддерживает ли реализация строгий режим:
var hasStrictMode = (function() { "use strict"; return this===undefined }());
  • Также, когда функция вызывается с call() или apply в строгом режиме, this точно значение первого аргумента call() или apply() . (В нормальном режиме null и undefined заменяются глобальным Object а значения, которые не являются объектами, преобразуются в объекты.)

  • В строгом режиме вы получите TypeError , когда вы пытаетесь назначить свойства readonly или определить новые свойства для не растяжимого объекта. (В обычном режиме оба просто обходятся без сообщения об ошибке.)

  • В строгом режиме при передаче кода в eval() вы не можете объявлять или определять переменные или функции в области вызывающего (как это можно сделать в обычном режиме). Вместо этого для eval() создается новая область, и переменные и функции находятся в пределах этой области. Эта область уничтожается после того, как eval() завершает выполнение.
  • В строгом режиме аргумент-объект функции содержит статическую копию значений, которые передаются этой функции. В нормальном режиме аргумент-объект имеет несколько «магическое» поведение: элементы массива и именованные функциональные параметры ссылаются на одно и то же значение.
  • В строгом режиме вы получите SyntaxError когда за оператором delete следует неквалифицированный идентификатор (переменная, функция или параметр функции). В нормальном режиме выражение delete ничего не сделает и будет оценено как false .
  • В строгом режиме вы получите TypeError при попытке удалить неконфигурируемое свойство. (В обычном режиме попытка просто терпит неудачу, а выражение delete - false ).
  • В строгом режиме это считается синтаксической ошибкой при попытке определить несколько свойств с тем же именем для литерала объекта. (В нормальном режиме ошибки нет.)
  • В строгом режиме это считается синтаксической ошибкой, когда объявление функции имеет несколько параметров с тем же именем. (В нормальном режиме ошибки нет.)
  • В строгом режиме не допускаются восьмеричные литералы (это литералы, начинающиеся с 0x . (В нормальном режиме некоторые реализации позволяют делать восьмеричные литералы).
  • В строгом режиме идентификаторы eval и arguments обрабатываются как ключевые слова. Вы не можете изменить их значение, не можете присвоить им значение, и вы не можете использовать их в качестве имен для переменных, функций, параметров функций или идентификаторов блока catch.
  • В строгом режиме больше ограничений на возможности проверки стека вызовов. arguments.caller и arguments.callee вызывают TypeError в функции в строгом режиме. Кроме того, некоторые свойства вызова и аргументов функций в строгом режиме вызывают TypeError при попытке их прочитать.



Использование 'use strict'; не делает ваш код лучше.

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

'use strict';

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

Рассмотрим этот пример:

var a = 365;
var b = 030;

В своей одержимости, чтобы выстроить числовые литералы, разработчик непреднамеренно инициализировал переменную b восьмым литералом. Нестрогий режим будет интерпретировать это как числовой литерал со значением 24 (в базе 10). Однако строгий режим вызовет ошибку.

Для не исчерпывающего списка специальностей в строгом режиме см. Этот ответ .

Где я должен использовать 'use strict'; ?

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

  • В моем существующем JavaScript-коде: Наверное, нет! Если в вашем существующем JavaScript-коде есть инструкции, которые запрещены в строгом режиме, приложение просто сломается. Если вам нужен строгий режим, вы должны быть готовы отлаживать и исправлять существующий код. Вот почему использование 'use strict'; не делает ваш код лучше .

Как использовать строгий режим?

  1. Вставить 'use strict'; в верхней части вашего скрипта:

    // File: myscript.js
    
    'use strict';
    var a = 2;
    ....
    

    Обратите внимание, что все в файле myscript.js будет интерпретироваться в строгом режиме.

  2. Или вставьте 'use strict'; утверждение сверху вашего тела функции:

    function doSomething() {
        'use strict';
        ...
    }
    

    Все в лексическом объеме функции doSomething будет интерпретироваться в строгом режиме. Здесь важна лексическая область слова. См. Этот ответ для лучшего объяснения.

Какие вещи запрещены в строгом режиме?

Я нашел хорошую статью, описывающую несколько вещей, которые запрещены в строгом режиме (обратите внимание, что это не эксклюзивный список):

Объем

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

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

Одним из преимуществ строгого кода является то, что такие инструменты, как YUI Compressor, могут выполнять лучшую работу при его обработке.

Подразумеваемые глобальные переменные

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

Глобальный утечек

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

Шумная ошибка

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

восьмеричный

8-разрядное представление чисел было чрезвычайно полезным при выполнении машинного программирования на машинах, размер слов которых был кратным 3. При работе с мэйнфреймом CDC 6600, имеющим размер слова 60 бит, вам понадобилось восьмеричное. Если бы вы могли читать восьмеричные, вы могли бы посмотреть на слово как на 20 цифр. Две цифры представляли op-код, а одна цифра идентифицировала один из 8 регистров. Во время медленного перехода от машинных кодов к языкам высокого уровня считалось полезным обеспечить восьмеричные формы на языках программирования.

В C было выбрано крайне неудачное представление о октальности: ведущий ноль. Так что в C 0100 означает 64, а не 100, а 08 - ошибка, а не 8. Еще более, к сожалению, этот анахронизм был скопирован почти на все современные языки, включая JavaScript, где он используется только для создания ошибок. Это не имеет другой цели. Таким образом, в строгом режиме восьмеричные формы больше не допускаются.

Et cetera

Аргументы pseudo array становятся немного более похожими на массивы в ES5. В строгом режиме он теряет свойства callee и caller . Это позволяет передавать ваши arguments ненадежному коду, не оставляя много конфиденциального контекста. Кроме того, свойство arguments функций исключается.

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

Зарезервированные слова для будущих версий JavaScript

ECMAScript 5 добавляет список зарезервированных слов. Если вы используете их как переменные или аргументы, строгий режим выдаст ошибку. Зарезервированные слова:

implements , interface , let , package , private , protected , public , static и yield

Дальнейшее чтение




Related