Was ist der „strenge Modus“ und wie wird er verwendet?

134

Ich habe die JavaScript-Referenz im Mozilla Developer Network durchgesehen und bin auf etwas gestoßen, das so genannt wird "strict mode". Ich habe es durchgelesen und habe Probleme zu verstehen, was es tut. Kann jemand (allgemein) kurz erklären, was sein Zweck ist und wie er nützlich ist?

nkcmr
quelle
2
Siehe auch
sampathsris

Antworten:

149

Sein Hauptzweck ist es, mehr zu überprüfen.

Fügen Sie einfach "use strict";oben in Ihren Code ein, bevor Sie etwas anderes tun.

Zum Beispiel blah = 33;ist gültiges JavaScript. Dies bedeutet, dass Sie eine vollständig globale Variable erstellen blah.

Im strengen Modus ist dies jedoch ein Fehler, da Sie das Schlüsselwort "var" nicht zum Deklarieren der Variablen verwendet haben.

Meistens wollen Sie keine globalen Variablen in der Mitte eines beliebigen Bereichs erstellen. In den meisten blah = 33Fällen handelt es sich also um einen Fehler, und der Programmierer wollte nicht, dass es sich um eine globale Variable handelt schreiben var blah = 33.

In ähnlicher Weise sind viele Dinge, die technisch gültig sind, nicht zulässig. NaN = "lol"erzeugt keinen Fehler. Es ändert auch nicht den Wert von NaN. Die Verwendung von strict this (und ähnlichen seltsamen Aussagen) führt zu Fehlern. Die meisten Leute wissen das zu schätzen, weil es keinen Grund gibt, jemals zu schreiben NaN = "lol", also gab es höchstwahrscheinlich einen Tippfehler.

Weitere Informationen finden Sie auf der MDN-Seite zum strengen Modus

Simon Sarris
quelle
4
Dies ist ein genaues Duplikat der Dokumentation bei MDN
nkcmr
23
Was verstehen Sie dann nicht über seine Nützlichkeit? Es soll die Entwicklung unterstützen, indem Dinge erfasst werden, die gültig, aber höchstwahrscheinlich fehlerhaft sind.
Simon Sarris
34

Ein Aspekt des strengen Modus, der in Simons Antwort nicht bereits erwähnt wurde, ist, dass der strenge Modus thisauf undefinedFunktionen gesetzt ist, die durch Funktionsaufruf aufgerufen werden.

Also solche Dinge

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

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

verursacht beim Aufrufen einen Fehler privateMethod(da Sie keine Eigenschaft hinzufügen können undefined), anstatt bdem globalen Objekt sinnlos eine Eigenschaft hinzuzufügen .

Adam Rackis
quelle
4
Ja, privateMethod.bind(this)();new jsbin.com
ich
Wichtigste Einschränkungen im strengen Modus: docs.microsoft.com/en-us/scripting/javascript/advanced/…
Krishna Mohan
21

Der strikte Modus wurde hinzugefügt, damit es eine leicht statisch analysierbare Teilmenge von EcmaScript gibt, die ein gutes Ziel für zukünftige Versionen der Sprache ist. Der strikte Modus wurde auch in der Hoffnung entwickelt, dass Entwickler, die sich auf den strengen Modus beschränken, weniger Fehler machen und sich die Fehler, die sie machen, auf offensichtlichere Weise manifestieren.

Harmony , die hoffentlich die nächste Hauptversion von EcmaScript sein wird, wird auf ES5 strict aufbauen.

Harmony baut auf dem strengen ES5-Modus auf, um zu viele Modi zu vermeiden.

Einige andere Sprachexperimente hängen ebenfalls vom strengen Modus ab. SES hängt von der Analysierbarkeit des ES5-Strict-Modus ab.

SES-Designexperiment (Secure ECMAScript)

Entwerfen Sie eine Programmiersprache für Objektfunktionen, indem Sie Funktionen in ES5 / Strict entfernen oder reparieren.

Es sollte eine einfache Übersetzung von SES nach ES5 / Strict geben.

Anhang C der Norm erläutert die Unterschiede zwischen dem strengen Modus und dem normalen Modus.

Die strengen Modusbeschränkungen und Ausnahmen

  • Die Bezeichner "implementiert", "Schnittstelle", "lassen", "Paket", "privat", "geschützt", "öffentlich", "statisch" und "Ausbeute" werden innerhalb des strengen Moduscodes als FutureReservedWord-Token klassifiziert. (7.6.12 [?]).
  • Eine konforme Implementierung kann bei der Verarbeitung von Code im strengen Modus die Syntax von NumericLiteral (7.8.3) möglicherweise nicht um OctalIntegerLiteral erweitern, wie in B.1.1 beschrieben.
  • Eine konforme Implementierung kann bei der Verarbeitung von Code im strengen Modus (siehe 10.1.1) die Syntax von EscapeSequence möglicherweise nicht um OctalEscapeSequence erweitern, wie in B.1.2 beschrieben.
  • Durch die Zuweisung zu einem nicht deklarierten Bezeichner oder einer anderweitig nicht auflösbaren Referenz wird keine Eigenschaft im globalen Objekt erstellt. Wenn eine einfache Zuweisung innerhalb eines strengen Moduscodes erfolgt, darf LeftHandSide nicht zu einer nicht auflösbaren Referenz ausgewertet werden. In diesem Fall wird eine ReferenceError-Ausnahme ausgelöst (8.7.2). Die LeftHandSide darf auch kein Verweis auf eine Dateneigenschaft mit dem Attributwert {[[Writable]]: false}, auf eine Accessoreigenschaft mit dem Attributwert {[[Set]]: undefined} oder auf eine nicht vorhandene Eigenschaft sein Eigenschaft eines Objekts, dessen interne Eigenschaft [[Extensible]] den Wert false hat. In diesen Fällen wird eine TypeError-Ausnahme ausgelöst (11.13.1).
  • Der Bezeichner eval oder die Argumente werden möglicherweise nicht als LeftHandSideExpression eines Zuweisungsoperators (11.13) oder eines PostfixExpression (11.3) oder als UnaryExpression angezeigt, die von einem Operator für Präfixinkremente (11.4.4) oder Präfixdekremente (11.4.5) ausgeführt wird . Argumente Objekte für Funktionen im strengen Modus definieren nicht konfigurierbare Accessor-Eigenschaften mit den Namen "caller" und "callee", die beim Zugriff eine TypeError-Ausnahme auslösen (10.6).
  • Argumente Objekte für Funktionen im strengen Modus teilen ihre Array-indizierten Eigenschaftswerte nicht dynamisch mit den entsprechenden formalen Parameterbindungen ihrer Funktionen. (10.6). Wenn für Funktionen im strengen Modus ein Argumentobjekt erstellt wird, ist die Bindung der lokalen Bezeichnerargumente an das Argumentobjekt unveränderlich und daher möglicherweise nicht das Ziel eines Zuweisungsausdrucks. (10.5).
  • Es ist ein SyntaxError, wenn der Code für den strengen Modus ein ObjectLiteral mit mehr als einer Definition einer Dateneigenschaft enthält (11.1.5). Es ist ein SyntaxError, wenn der Bezeichner "eval" oder der Bezeichner "argument" als Bezeichner in einer PropertySetParameterList einer PropertyAssignment vorkommt, die in einem strengen Code enthalten ist, oder wenn sein FunctionBody ein strenger Code ist (11.1.5).
  • Auswertungscode im strengen Modus kann keine Variablen oder Funktionen in der Variablenumgebung des aufzurufenden Aufrufers instanziieren. Stattdessen wird eine neue Variablenumgebung erstellt und diese Umgebung wird für die Instanziierung der Deklarationsbindung für den Eval-Code (10.4.2) verwendet.
  • Wenn dies innerhalb des strengen Moduscodes ausgewertet wird, wird dieser Wert nicht zu einem Objekt gezwungen. Ein Wert von null oder undefiniert wird nicht in das globale Objekt konvertiert, und primitive Werte werden nicht in Wrapper-Objekte konvertiert. Der über einen Funktionsaufruf übergebene Wert (einschließlich der mit Function.prototype.apply und Function.prototype.call getätigten Aufrufe) erzwingt nicht die Übergabe dieses Werts an ein Objekt (10.4.3, 11.1.1, 15.3.4.3, 15.3). 4.4).
  • Wenn ein Löschoperator innerhalb eines strengen Moduscodes auftritt, wird ein SyntaxError ausgelöst, wenn sein UnaryExpression ein direkter Verweis auf eine Variable, ein Funktionsargument oder einen Funktionsnamen ist (11.4.1).
  • Wenn ein Löschoperator innerhalb des strengen Moduscodes auftritt, wird ein TypeError ausgelöst, wenn die zu löschende Eigenschaft das Attribut {[[Konfigurierbar]]: false} (11.4.1) aufweist. Es ist ein SyntaxError, wenn eine VariableDeclaration oder VariableDeclarationNoIn innerhalb eines strengen Codes vorkommt und sein Bezeichner eval oder Argumente ist (12.2.1).
  • Der Code für den strengen Modus enthält möglicherweise kein WithStatement. Das Auftreten eines WithStatements in einem solchen Kontext ist ein SyntaxError (12.10).
  • Es ist ein SyntaxError, wenn ein TryStatement mit einem Catch innerhalb eines strengen Codes auftritt und der Bezeichner der Catch-Produktion eval oder Argumente ist (12.14.1).
  • Es ist ein SyntaxError, wenn der Bezeichner eval oder die Argumente in einer FormalParameterList eines strengen Modus FunctionDeclaration oder FunctionExpression (13.1) angezeigt werden.
  • Eine Funktion für den strengen Modus verfügt möglicherweise nicht über zwei oder mehr formale Parameter mit demselben Namen. Ein Versuch, eine solche Funktion mit einem FunctionDeclaration-, FunctionExpression- oder Function-Konstruktor zu erstellen, ist ein SyntaxError (13.1, 15.3.2).
  • Eine Implementierung darf nicht über die in dieser Spezifikation definierten Bedeutungen innerhalb von Funktionen im strengen Modus von Eigenschaften mit dem Namen caller oder Argumenten von Funktionsinstanzen hinausgehen. ECMAScript-Code darf keine Eigenschaften mit diesen Namen für Funktionsobjekte erstellen oder ändern, die strengen Modusfunktionen entsprechen (10.6, 13.2, 15.3.4.5.3).
  • Es ist ein SyntaxError, innerhalb von Code im strengen Modus die Bezeichner eval oder Argumente als Bezeichner einer FunctionDeclaration oder FunctionExpression oder als formalen Parameternamen (13.1) zu verwenden. Wenn Sie versuchen, eine solche strenge Modusfunktion mithilfe des Funktionskonstruktors (15.3.2) dynamisch zu definieren, wird eine SyntaxError-Ausnahme ausgelöst.
Mike Samuel
quelle
6

ECMAScript 5 führte das Konzept des strengen Modus ein .

Aufrufen des Strict-Modus im Code

Der strikte Modus gilt für ganze Skripte oder für einzelne Funktionen. Es gilt nicht für Blockanweisungen in {} Klammern. Der Versuch, sie auf solche Kontexte anzuwenden, führt zu nichts.

Gesamtes Skript:

Angenommen, wir erstellen app.js, sodass durch Hinzufügen eines Skripts zur Verwendung der ersten Anweisung der strikte Modus für den gesamten Code erzwungen wird.

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

Strenger Funktionsmodus:

Um den strengen Modus für eine Funktion aufzurufen, geben Sie die genaue Anweisung "use strict" ein. am Anfang des Funktionskörpers vor jeder anderen Anweisung.

function yourFunc(){
 "use strict";

 // Your function code logic
}

Der strikte Modus enthält mehrere Änderungen an der normalen Javascript-Semantik. Im ersten strengen Modus werden einige stille JavaScript-Fehler beseitigt, indem sie geändert werden, um Fehler auszulösen.

Zum Beispiel: Code im strengen Modus

Geben Sie hier die Bildbeschreibung ein

Im obigen Codebeispiel ohne Verwendung des strengen Modus im Code wird kein Fehler ausgegeben. Da wir auf Variablen zugreifen, xohne sie zu deklarieren. Wenn Sie also im strengen Modus auf nicht deklarierte Variablen zugreifen, wird ein Fehler ausgegeben.

Versuchen wir nun, auf die Variable x zuzugreifen, ohne sie ohne strengen Modus zu deklarieren.

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

// Will not throw an error

Vorteil der Verwendung des strengen Modus:

  • Beseitigen Sie stille JavaScript-Fehler, indem Sie Fehler auslösen.
  • Behebt Fehler, die es der JavaScript-Engine erschweren, eine Optimierung durchzuführen.
  • Lassen Sie Code manchmal schneller laufen als identischen Code, der sich nicht im strengen Modus befindet
  • Verbietet eine Syntax, die wahrscheinlich in zukünftigen Versionen von ECMAScript definiert wird.
Nishant Kumar
quelle
5

Im strengen Modus werden mehrere Änderungen an der normalen JavaScript-Semantik vorgenommen.

  • Der strikte Modus eliminiert einige stille JavaScript-Fehler, indem sie geändert werden, um Fehler auszulösen.

  • Der strikte Modus behebt Fehler, die es JavaScript-Engines erschweren, Optimierungen durchzuführen.

  • Der strikte Modus verbietet eine Syntax, die wahrscheinlich in zukünftigen Versionen von ECMAScript definiert wird.

Renganathan MG
quelle
1

ECMAScript5 führt einige neue Objekte und Eigenschaften sowie die sogenannten "strict mode" .

Der strikte Modus ist eine Teilmenge der Sprache, die veraltete Funktionen ausschließt. Der strikte Modus ist opt-in und nicht erforderlich. Wenn Sie also möchten, dass Ihr Code im strengen Modus ausgeführt wird, erklären Sie Ihre Absicht mit (einmal pro Funktion oder einmal für das gesamte Programm) der folgenden Zeichenfolge:

"use strict";
Vahid Hallaji
quelle
1

2017 und ich habe endlich die Dokumentation gefunden:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

Der strikte Modus ist eine Möglichkeit, sich für eine eingeschränkte Variante von JavaScript zu entscheiden. Der strikte Modus ist nicht nur eine Teilmenge: Er hat absichtlich eine andere Semantik als normaler Code. Browser, die den strengen Modus nicht unterstützen, führen den Code für den strengen Modus mit einem anderen Verhalten aus als Browser, die dies tun. Verlassen Sie sich daher nicht auf den strengen Modus ohne Funktionstests, um die relevanten Aspekte des strengen Modus zu unterstützen. Strenger Moduscode und nicht strenger Moduscode können nebeneinander existieren, sodass Skripte schrittweise in den strengen Modus wechseln können.


Im strengen Modus werden mehrere Änderungen an der normalen JavaScript-Semantik vorgenommen. Erstens beseitigt der strikte Modus einige stille JavaScript-Fehler, indem sie geändert werden, um Fehler auszulösen. Zweitens behebt der strikte Modus Fehler, die es JavaScript-Engines erschweren, Optimierungen durchzuführen: Der Code für den strengen Modus kann manchmal schneller ausgeführt werden als identischer Code, der kein strenger Modus ist. Drittens verbietet der strikte Modus eine Syntax, die wahrscheinlich in zukünftigen Versionen von ECMAScript definiert wird.

Tilak Maddy
quelle
0

Frage: Das
folgende Problem ist aufgetreten. Ich habe ein Tutorial befolgt und versucht, die folgende scssDatei zu kompilieren und daraus CSS-Code zu generieren.

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

mit folgender gulpfile.jsAufgabe:

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'))
});

Der Fehler, den ich bekomme, lautet also wie folgt:

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

Lösung:
Es zeigt mir also eine index.jsDatei, die sich in meinem gulp-sass-Modul befindet (die grundsätzlich gesperrt ist und nicht bearbeitet werden sollte). Aber wenn ich energisch gehe und "use_strict"das oben drauf hinzufügeindex.js Datei einfüge, läuft meine Aufgabe reibungslos.

Ich war hilflos und benutze dies weiterhin als Lösung! Aber nachdem ich einige andere SO Q & A's durchgesehen hatte, sah ich folgende Antwort wie folgt:

sudo npm install -g n
sudo n stable

und früher habe ich meine NodeJs (auf Version 10.x) aktualisiert und dann Gulp neu erstellt, indem ich die folgenden Befehle ausgeführt habe, wie es mir das Terminal angewiesen hat:

npm rebuild node-sass --force

Und es ist alles in Ordnung. So wurde es gelöst. Ich habe die Änderungen, für die ich sie vorgenommen habe, rückgängig gemachtindex.js gulp-Moduldatei vorgenommen . Und jetzt läuft es reibungslos.

Hoffe, diese Antwort wird jemandem da draußen hilfreich sein!

Randika Vishman
quelle