Was macht "Use Strict" in JavaScript und was ist der Grund dafür?


Answers

Es ist ein neues Feature von ECMAScript 5. John Resig hat eine nette Zusammenfassung davon geschrieben.

Es ist nur eine Zeichenfolge, die Sie in Ihre JavaScript-Dateien einfügen (entweder oben in der Datei oder innerhalb einer Funktion), die wie folgt aussieht:

"use strict";

Wenn Sie es jetzt in Ihren Code einfügen, sollte dies keine Probleme mit den aktuellen Browsern verursachen, da es sich nur um eine Zeichenfolge handelt. Es kann in Zukunft zu Problemen mit Ihrem Code führen, wenn Ihr Code gegen das Pragma verstößt. Wenn Sie zum Beispiel foo = "bar" ohne zuerst foo zu definieren, wird Ihr Code fehlschlagen ... was meiner Meinung nach eine gute Sache ist.

Question

Kürzlich habe ich einen Teil meines JavaScript-Codes durch Crockfords JSLint und folgende Fehlermeldung ausgegeben:

Problem bei Zeile 1 Zeichen 1: Fehlende Anweisung "use strict".

Als ich ein wenig gesucht habe, habe ich festgestellt, dass einige Leute "use strict"; hinzufügen "use strict"; in ihren JavaScript-Code. Sobald ich die Anweisung hinzugefügt habe, wurde der Fehler nicht mehr angezeigt. Leider hat Google nicht viel von der Geschichte hinter dieser Zeichenfolgenaussage verraten. Sicher muss es etwas damit zu tun haben, wie das JavaScript vom Browser interpretiert wird, aber ich habe keine Ahnung, was der Effekt wäre.

Also, was ist "use strict"; worum geht es, und ist es noch relevant?

Reagieren einige der aktuellen Browser auf "use strict"; String oder ist es für zukünftige Verwendung?




"Strenge verwenden"; ist eine Versicherung, dass Programmierer die losen oder die schlechten Eigenschaften von JavaScript nicht verwenden werden. Es ist ein Leitfaden, genau wie ein Lineal Ihnen helfen wird, gerade Linien zu machen. "Use Strict" hilft Ihnen beim "Straight Coding".

Diejenigen, die es vorziehen, keine Lineale zu verwenden, um ihre Zeilen geradeaus zu machen, landen normalerweise auf diesen Seiten und verlangen, dass andere ihren Code debuggen.

Das können Sie mir glauben. Der Overhead ist im Vergleich zu schlecht entworfenem Code vernachlässigbar. Doug Crockford, seit einigen Jahren Senior JavaScript Entwickler, hat hier einen sehr interessanten Beitrag . Persönlich möchte ich immer wieder auf seine Seite zurückkehren, um sicherzustellen, dass ich meine gute Praxis nicht vergesse.

Die moderne JavaScript-Praxis sollte immer das "Use Strict" hervorrufen; Pragma. Der einzige Grund, warum die ECMA-Gruppe den "Strengen" -Modus optional gemacht hat, besteht darin, weniger erfahrenen Programmierern den Zugriff auf JavaScript zu erlauben und ihnen Zeit zu geben, sich an die neuen und sichereren Programmierverfahren anzupassen.




Verwenden Sie 'use strict'; macht deinen Code nicht plötzlich besser.

Der strikte JavaScript-Modus ist eine Funktion in ECMAScript 5 . Sie können den strikten Modus aktivieren, indem Sie dies oben im Skript / in der Funktion deklarieren.

'use strict';

Wenn eine JavaScript-Engine diese Anweisung erkennt , beginnt sie, den Code in einem speziellen Modus zu interpretieren. In diesem Modus werden Fehler ausgelöst, wenn bestimmte Programmierpraktiken entdeckt werden, die potentielle Fehler sein könnten (was der Grund für den strikten Modus ist).

Betrachten Sie dieses Beispiel:

var a = 365;
var b = 030;

In ihrer Obsession, die numerischen Literale aufzureihen, hat der Entwickler die Variable b mit einem Oktal-Literal initialisiert. Der nicht strikte Modus interpretiert dies als ein numerisches Literal mit dem Wert 24 (in der Basis 10). Der strikte Modus wird jedoch einen Fehler auslösen.

Eine nicht erschöpfende Liste von Spezialitäten im strikten Modus finden Sie in dieser Antwort .

Wo soll ich 'use strict'; ?

  • In meiner neuen JavaScript-Anwendung: Absolut! Der Strict-Modus kann als Whistleblower verwendet werden, wenn Sie etwas Dummes mit Ihrem Code machen.

  • In meinem bestehenden JavaScript-Code: Wahrscheinlich nicht! Wenn Ihr vorhandener JavaScript-Code Anweisungen enthält, die im Strict-Modus nicht zulässig sind, wird die Anwendung einfach unterbrochen. Wenn Sie den strikten Modus verwenden möchten, sollten Sie bereit sein, Ihren vorhandenen Code zu debuggen und zu korrigieren. Aus diesem Grund verwenden Sie 'use strict'; macht deinen Code nicht plötzlich besser .

Wie verwende ich den strikten Modus?

  1. Fügen Sie ein 'use strict'; Aussage oben auf Ihrem Skript:

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

    Beachten Sie, dass alles in der Datei myscript.js im strikten Modus interpretiert wird.

  2. Oder fügen Sie ein 'use strict'; Aussage oben auf Ihrem Funktionskörper:

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

    Alles im lexikalischen Funktionsumfang doSomething wird im strikten Modus interpretiert. Das Wort lexical scope ist hier wichtig. Siehe diese Antwort für eine bessere Erklärung.

Was ist im strikten Modus verboten?

Ich habe einen schönen Artikel gefunden , der mehrere Dinge beschreibt, die im strikten Modus verboten sind (beachten Sie, dass dies keine exklusive Liste ist):

Umfang

Historisch gesehen war JavaScript verwirrt darüber, wie Funktionen eingeschränkt sind. Manchmal scheinen sie statisch begrenzt zu sein, aber einige Features verhalten sich wie dynamische Bereiche. Dies ist verwirrend und erschwert das Lesen und Verstehen von Programmen. Missverständnis verursacht Fehler. Es ist auch ein Problem für die Leistung. Statisches Scoping würde ermöglichen, dass eine variable Bindung zur Kompilierungszeit stattfindet, aber die Anforderung für einen dynamischen Bereich bedeutet, dass die Bindung auf die Laufzeit verschoben werden muss, was mit einer erheblichen Leistungseinbuße einhergeht.

Der strikte Modus erfordert, dass alle Variablenbindungen statisch ausgeführt werden. Das bedeutet, dass die Features, die zuvor eine dynamische Bindung erforderten, eliminiert oder geändert werden müssen. Insbesondere wird die with-Anweisung eliminiert, und die Fähigkeit der eval-Funktion, die Umgebung ihres Aufrufers zu manipulieren, ist stark eingeschränkt.

Einer der Vorteile von striktem Code ist, dass Tools wie YUI Compressor bei der Verarbeitung einen besseren Job machen können.

Implizierte globale Variablen

JavaScript hat globale Variablen impliziert. Wenn Sie eine Variable nicht explizit deklarieren, wird implizit eine globale Variable für Sie deklariert. Dies erleichtert Anfängern die Programmierung, da sie einige ihrer grundlegenden Hausaufgaben vernachlässigen können. Es erschwert jedoch die Verwaltung größerer Programme und verschlechtert die Zuverlässigkeit erheblich. Im strikten Modus werden also implizite globale Variablen nicht mehr erstellt. Sie sollten alle Ihre Variablen explizit deklarieren.

Globale Leckage

Es gibt eine Reihe von Situationen, die dazu führen this , dass dies an das globale Objekt gebunden wird. Wenn Sie zum Beispiel vergessen, beim Aufruf einer Konstruktorfunktion das new Präfix anzugeben, wird this Konstrukt unerwartet an das globale Objekt gebunden. Statt also ein neues Objekt zu initialisieren, manipuliert es stattdessen stillschweigend globale Variablen. In diesen Situationen bindet der strikte Modus dies stattdessen an undefined , wodurch der Konstruktor stattdessen eine Ausnahme auslöst, wodurch der Fehler viel früher erkannt werden kann.

Lautes Versagen

JavaScript hatte immer schreibgeschützte Eigenschaften, aber Sie konnten sie nicht selbst erstellen, bis die Object.createProperty Funktion von Object.createProperty diese Fähigkeit offen legte. Wenn Sie versucht haben, einer schreibgeschützten Eigenschaft einen Wert zuzuweisen, schlägt sie automatisch fehl. Die Zuweisung würde den Wert der Eigenschaft nicht ändern, aber Ihr Programm würde so weitermachen, als ob es hätte. Dies ist eine Integritätsgefahr, die dazu führen kann, dass Programme in einen inkonsistenten Zustand geraten. Im strikten Modus wird beim Versuch, eine schreibgeschützte Eigenschaft zu ändern, eine Ausnahme ausgelöst.

Oktal

Die oktale (oder base 8) Darstellung von Zahlen war extrem nützlich, wenn man Maschinen auf Maschinenebene programmiert, deren Wortgrößen ein Vielfaches von 3 waren. Bei der Arbeit mit dem CDC 6600 Mainframe, der eine Wortgröße von 60 Bits hatte, war Octal erforderlich. Wenn Sie oktal lesen könnten, könnten Sie ein Wort als 20 Ziffern betrachten. Zwei Ziffern repräsentierten den Op-Code, und eine Ziffer identifizierte eines von 8 Registern. Während des langsamen Übergangs von Maschinencodes zu Hochsprachen wurde es für nützlich gehalten, Oktalformen in Programmiersprachen bereitzustellen.

In C wurde eine extrem unglückliche Darstellung der Oktalität gewählt: Leitende Null. In C bedeutet 0100 also 64, nicht 100, und 08 ist ein Fehler, nicht 8. Noch mehr leider wurde dieser Anachronismus in fast alle modernen Sprachen kopiert, einschließlich JavaScript, wo er nur zum Erzeugen von Fehlern verwendet wird. Es hat keinen anderen Zweck. Im strikten Modus sind also oktale Formen nicht mehr erlaubt.

Und so weiter

Das Argumenten-Pseudo-Array wird in ES5 etwas mehr Array-artig. Im strikten Modus verliert es seine callee und caller . Auf diese Weise können Sie Ihre arguments an nicht vertrauenswürdigen Code übergeben, ohne viel vertraulichen Kontext aufzugeben. Außerdem wird die arguments -Eigenschaft von Funktionen eliminiert.

Im strikten Modus erzeugen doppelte Schlüssel in einem Funktionsliteral einen Syntaxfehler. Eine Funktion kann nicht zwei Parameter mit demselben Namen haben. Eine Funktion darf keine Variable mit demselben Namen wie einer ihrer Parameter haben. Eine Funktion kann ihre eigenen Variablen nicht delete . Ein Versuch, eine nicht konfigurierbare Eigenschaft zu delete , delete jetzt eine Ausnahme aus. Primitive Werte werden nicht implizit umschlossen.

Reservierte Wörter für zukünftige JavaScript-Versionen

ECMAScript 5 fügt eine Liste reservierter Wörter hinzu. Wenn Sie sie als Variablen oder Argumente verwenden, wird im strikten Modus ein Fehler ausgegeben. Die reservierten Wörter sind:

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

Weiterführende Literatur




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.



Wenn Sie einen Browser verwenden, der im letzten Jahr veröffentlicht wurde, wird wahrscheinlich der JavaScript Strict-Modus unterstützt. Nur ältere Browser, bevor ECMAScript 5 zum aktuellen Standard wurde, unterstützen dies nicht.

Die Anführungszeichen um den Befehl stellen sicher, dass der Code auch in älteren Browsern funktioniert (obwohl die Dinge, die im strikten Modus einen Syntaxfehler erzeugen, in der Regel nur dazu führen, dass das Skript in diesen älteren Browsern schwer zu erkennen ist).




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
    Fehler.

  • 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.




"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.




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. Z.B:

    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 .




Wenn Leute sich Sorgen machen über die Verwendung von use strict , könnte es sich lohnen, diesen Artikel zu lesen:

ECMAScript 5 'Strict Mode' Unterstützung in Browsern. Was bedeutet das?
NovoGeek.com - Krishnas Weblog

Es geht um Browser-Unterstützung, aber vor allem, wie man damit sicher umgehen kann:

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.
*/



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.




Ich möchte eine etwas fundiertere Antwort anbieten, die die anderen Antworten ergänzt. Ich hatte gehofft, die beliebteste Antwort zu bearbeiten, scheiterte aber. Ich habe versucht, es so umfassend und vollständig wie möglich zu gestalten.

Weitere Informationen finden Sie in der MDN-Dokumentation .

"use strict" eine in ECMAScript 5 eingeführte Direktive.

Richtlinien sind Aussagen ähnlich, jedoch anders.

  • use strict enthält keine Schlüsselwörter: Die Direktive ist eine einfache Ausdruckanweisung, die aus einem speziellen String-Literal (in einfachen oder doppelten Anführungszeichen) besteht. JavaScript-Engines, die ECMAScript 5 nicht implementieren, sehen lediglich eine Ausdrucksanweisung ohne Nebenwirkungen. Es wird erwartet, dass zukünftige Versionen von ECMAScript-Standards die use als echtes Schlüsselwort einführen; die Zitate würden dadurch obsolet werden.
  • use strict kann nur am Anfang eines Skripts oder einer Funktion verwendet werden, dh es muss jeder anderen (realen) Anweisung vorausgehen. Es muss nicht die erste Anweisung in einem Funktionsskript sein: Es können andere Anweisungsausdrücke vorangestellt werden, die aus Zeichenfolgenliteralen bestehen (und JavaScript-Implementierungen können sie als implementierungsspezifische Anweisungen behandeln). String-Literale-Anweisungen, die einer ersten reellen Anweisung (in einem Skript oder einer Funktion) folgen, sind einfache Ausdruckanweisungen. Interpreten dürfen sie nicht als Direktiven interpretieren und haben keine Wirkung.

Die Anweisung use strict gibt an, dass der folgende Code (in einem Skript oder einer Funktion) ein strenger Code ist. Der Code auf der höchsten Ebene eines Skripts (Code, der nicht in einer Funktion enthalten ist) wird als strikter Code betrachtet, wenn das Skript eine use strict Anweisung enthält. Der Inhalt einer Funktion wird als strikter Code betrachtet, wenn die Funktion selbst in einem strikten Code definiert ist oder wenn die Funktion eine use strict Direktive enthält. Code, der an eine eval() -Methode übergeben wird, gilt als strikter Code, wenn eval() von einem strikten Code aufgerufen wurde oder die use strict Direktive selbst enthält.

Der strikte Modus von ECMAScript 5 ist eine eingeschränkte Teilmenge der JavaScript-Sprache, die relevante Sprachdefizite eliminiert und eine strengere Fehlerprüfung und höhere Sicherheit bietet. Im Folgenden werden die Unterschiede zwischen dem strikten Modus und dem normalen Modus aufgeführt (von denen die ersten drei besonders wichtig sind):

  • Sie können die with Anweisung nicht im strikten Modus verwenden.
  • Im strikten Modus müssen alle Variablen deklariert werden: Wenn Sie einem Bezeichner, der nicht als Variable, Funktion, Funktionsparameter, Parameter catch-clause oder Eigenschaft des globalen Object deklariert wurde, einen Wert zuweisen, erhalten Sie einen ReferenceError . Im normalen Modus wird der Bezeichner implizit als globale Variable (als Eigenschaft des globalen Object ) deklariert.
  • Im strikten Modus hat das Schlüsselwort den Wert undefined in Funktionen, die als Funktionen (nicht als Methoden) aufgerufen wurden. (Im Normalmodus zeigt this immer auf das globale Object ). Dieser Unterschied kann verwendet werden, um zu testen, ob eine Implementierung den strikten Modus unterstützt:
var hasStrictMode = (function() { "use strict"; return this===undefined }());
  • Wenn eine Funktion mit call() aufgerufen oder im strikten Modus angewendet wird, ist this genau der Wert des ersten Arguments des call() oder apply() call() . (Im normalen Modus werden null und undefined durch das globale Object und Werte, die keine Objekte sind, werden in Objekte umgewandelt.)

  • Im strikten Modus erhalten Sie einen TypeError , wenn Sie versuchen, schreibgeschützte Eigenschaften zuzuweisen oder neue Eigenschaften für ein nicht erweiterbares Objekt zu definieren. (Im normalen Modus scheitern beide einfach ohne Fehlermeldung.)

  • Im strikten Modus können Sie beim Übergeben von Code an eval() keine Variablen oder Funktionen im Bereich des Aufrufers deklarieren oder definieren (wie dies im normalen Modus möglich ist). Stattdessen wird ein neuer Bereich für eval() und die Variablen und Funktionen sind in diesem Bereich enthalten. Dieser Bereich wird zerstört, nachdem eval() Ausführung beendet hat.
  • Im strikten Modus enthält das arguments-Objekt einer Funktion eine statische Kopie der Werte, die an diese Funktion übergeben werden. Im normalen Modus hat das arguments-Objekt ein etwas "magisches" Verhalten: Die Elemente des Arrays und die benannten Funktionsparameter verweisen auf den gleichen Wert.
  • Im strikten Modus erhalten Sie einen SyntaxError wenn auf den delete ein nicht qualifizierter Bezeichner (ein Variablen-, Funktions- oder Funktionsparameter) folgt. Im normalen Modus würde der delete nichts tun und wird als false ausgewertet.
  • Im strikten Modus erhalten Sie einen TypeError wenn Sie versuchen, eine nicht konfigurierbare Eigenschaft zu löschen. (Im normalen Modus schlägt der Versuch einfach fehl und der delete wird als false bewertet).
  • Im strikten Modus wird es als ein syntaktischer Fehler angesehen, wenn Sie versuchen, mehrere Eigenschaften mit demselben Namen für ein Objektliteral zu definieren. (Im normalen Modus gibt es keinen Fehler.)
  • Im strikten Modus gilt es als syntaktischer Fehler, wenn eine Funktionsdeklaration mehrere Parameter mit demselben Namen hat. (Im normalen Modus gibt es keinen Fehler.)
  • Im strikten Modus sind oktale Literale nicht erlaubt (dies sind Literale, die mit 0x . (Im normalen Modus erlauben einige Implementierungen oktale Literale.)
  • Im strikten Modus werden die Bezeichner eval und arguments wie Schlüsselwörter behandelt. Sie können ihren Wert nicht ändern, ihnen keinen Wert zuweisen, und Sie können sie nicht als Namen für Variablen, Funktionen, Funktionsparameter oder Bezeichner eines catch-Blocks verwenden.
  • Im strikten Modus gibt es mehr Einschränkungen hinsichtlich der Möglichkeiten, den Call-Stack zu untersuchen. arguments.caller und arguments.callee verursachen einen TypeError in einer Funktion im strikten Modus. Darüber hinaus verursachen einige Aufrufer- und Argumenteigenschaften von Funktionen im strikten Modus beim Versuch, sie zu lesen, einen TypeError .



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() { } 
    

Quellen:




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.






Related