2010-02-26 9 views
39

Welchen Umfang hat das Pragma mit striktem Modus in ECMAScript5?Was bedeutet in ECMAScript5 "use strict"?

"use strict"; 

Ich möchte, dies zu tun (vor allem, weil JSLint nicht darüber beklagen):

"use strict"; 

(function() { 
    // my stuff here... 
}()); 

Aber ich bin nicht sicher, ob die anderen Code brechen würde oder nicht. Ich weiß, dass ich das tun kann, was wird Anwendungsbereich der Pragma auf die Funktion ...

(function() { 

    "use strict"; 

    // my stuff here... 

}()); 

aber JSLint beschwert sich darüber (wenn die „strenge“ JSLint Option aktiviert ist), weil es denkt, dass Sie Code ausführen bevor Sie "use strict" aktivieren.

Hier ist meine Frage. Wenn ich fileA.js haben:

"use strict"; 
// do some stuff 

und fileB.js:

eval(somecodesnippet); // disallowed by "use strict" 

und dann sind sie in meinem HTML-Seite in der gleichen Reihenfolge, wird die Pragma in die Datei scoped werden, oder wird das Pragma blutet in Datei B und blockiert damit die Eval-Ausführung?

+0

A-Seite Anmerkung: Douglad Crockfords Präsentation über "Der Zustand und die Zukunft von Javascript war wirklich großartig. Er diskutiert einige der neuen Funktionen wie streng am Ende des Vortrags. Hier ist der Link: http://www.infoq.com/presentations/The-State-and-Future-of-JavaScript –

+0

'eval()' ist erlaubt mit '" use strict "', es wird nur globale Reichweite. –

Antwort

2

BEARBEITEN Es scheint, dass ich falsch war. Bitte sehen Sie Jeff Walden's answer below.

Schauen Sie sich diese Antwort auf eine ähnliche Frage: What does "use strict" do in JavaScript, and what is the reasoning behind it?

Trotz JSLint Beschwerden, können Sie (und sollte) verwenden "use strict"; innerhalb einer Funktion, wenn Sie diese Funktion wollen im Strict-Modus sein. Wenn Sie es im globalen Kontext verwenden, erzwingt es, dass sich Ihr gesamter Code im strikten Modus befindet. Kurze Antwort: Ja, es wird Ihre Verwendung von eval blockieren.

+2

Diese Antwort ist falsch. Die Verwendung der Direktive am Anfang von 'fileA.js' bewirkt, dass die Gesamtheit dieser Datei im strikten Modus ist, aber' fileb.js' nicht im strikten Modus ist, unabhängig von der Reihenfolge, in der sie in der HTML-Seite enthalten sind . Außerdem funktioniert 'eval()' im strikten Modus anders, funktioniert aber immer noch. Es ist nicht "blockiert". –

54

"use strict" gilt nur für Funktion oder Programmbereich. Wenn Sie also fileA.js mit "use strict" an der Spitze haben, wird fileA.js im strikten Modus ausgeführt, und alle darin definierten Funktionen machen dasselbe, wenn sie aufgerufen werden. Aber dateiB.js ist ein separates Programm, so dass die Datei "use strict" von fileA.js nicht darauf zutrifft - und daher fileB.js im nicht strikten Modus ausgeführt wird. (Natürlich, wenn somecodesnippet mit einer "use strict" Direktive beginnt und richtig analysiert, wird dieser Code im strikten Modus ausgeführt, und Funktionen, die durch diesen Code definiert werden, werden ebenfalls ausgeführt.) Strenge absolut nicht "bluten" - und pro ES5 4.2.2 (zugegebenermaßen nicht normativ, aber ich bin mir sicher, dass ich bei Bedarf eine normative Referenz dafür ausgraben könnte), "eine Implementierung muss die Kombination von uneingeschränkten und strikten Modus-Code-Einheiten zu einem einzigen zusammengesetzten Programm unterstützen".

Ein Problem: Wenn Sie den strikten Modus im globalen Bereich manchmal, aber nicht immer verwenden, können Sie Ihre Skripte nicht mehr in einer einzigen Datei verketten. Angenommen, Sie haben die Skripte A, B, C, D in dieser Reihenfolge. Wenn A streng ist, wird die Gesamtverkettung streng sein, selbst wenn B/C/D nicht wäre! Umgekehrt, wenn A nicht streng ist (und nicht leer ist), wird die Gesamtverkettung nicht streng sein, selbst wenn B/C/D streng sind. Dies hat bereits mindestens eine Early-Adopter-Site gebissen.

Alles, was gesagt, strikt Modus verbietet nicht eval.Wenn eval der normale Weg im strikten Modus aufgerufen wird, mit der Programmsyntax der Form eval(code [, ...]), ist es ein "direktes" Eval, das sich so verhält eval hat immer - außer dass code immer als strict mode code ausgewertet wird, auch wenn code doesn ' t Beginnen Sie mit einer "use strict" Direktive, mit der Ausnahme, dass alle Variablen, die durch den Code erzeugt werden, in einem separaten Speicher von allen vorhandenen Variablen gespeichert werden. (Die genaue Semantik ist ein bisschen kompliziert; ich arbeite an der JavaScript-Engine von Firefox, in letzter Zeit implementiere ich diese Sachen, und selbst nach einiger Zeit in der Spezifikation und an einer Implementierung arbeite ich immer noch nicht intuitiv.)

Wenn es nicht so heißt - eval.call(...), setTimeout(eval, ...), setInterval(eval, ...), var ev = eval; ev(...);, und so weiter - es ist eine "indirekte" Eval. Indirekt eval (ob innerhalb oder außerhalb des strikten Modus) verhält sich ein wenig anders: Namensauflösung und Variablendefinition treten auf, als ob sie sich im globalen Gültigkeitsbereich befinden. (Der Code wird ausgeführt, wie Strict-Modus-Code nur dann, wenn sie mit einer "use strict" Richtlinie beginnt.)

Strict-Modus-Unterstützung ist fast - aber nicht vollständig - fertig in der neuesten Firefox nightlies, so es kann sich lohnen, ein Download zu spielen herum mit den Teilen des strikten Modus, die implementiert sind. Ich würde immer noch sagen, warten Sie auf die Verwendung der Produktion, bis es abgeschlossen ist, aber es ist definitiv bereit für Experimente (solange Sie verstehen, strengen Modus ist noch nicht vollständig). (Was Sean McMillans Link anbelangt, seien Sie sich bewusst, dass seine Behauptungen von "Support" das für jede Kugel erforderliche Minimum an Funktionalität darstellen. Die Strict-Mode-Tests sind viel besser, obwohl sie nicht annähernd den strikten Modus vollständig abdecken.)

+4

'Strenge absolut nicht' bluten '' - Das ist nicht ganz richtig. Sie können '.caller' in nicht-striktem Code nicht verwenden, wenn die Funktion, für die Sie sie verwenden, im strikten Modus definiert wurde. Also kann nicht-strikter Code in der Tat brechen, weil anderer Code im strikten Modus ist - ich würde das als Blutung betrachten. – AndreKR

+1

Wie die ursprüngliche Frage formuliert wurde, würde ich "bluten" im Sinne des lexikalischen, textuellen Quellcodes interpretieren - von Skript B, das die Striktheit von Skript A aufgreift, ohne sich selbst in Striktheit zu begeben. Offensichtlich sind die Auswirkungen eines Skripts (einschließlich solcher, die durch Strenge verursacht werden) sichtbar - "bluten", könnte man sagen - in anderen Skripten.Die * Natur * des Effekts kann abhängig von der Strenge des auslösenden Skripts variieren. Aber streng oder nicht, Effekte eines Skripts sind im anderen sichtbar. Das scheint mir keine besonders nützliche Definition von "bluten" zu sein. –

0
eval(somecodesnippet); // disallowed by "use strict" 

Nicht, wenn Sie erklären somecodesnippet vor.

var somecodesnippet = "Ihr tolles Codesnippet hier";

eval (somecodesnippet); // NICHT "use strict" nicht zulässig

0

Die gesamte Datei:

<script...> 
    "use strict"; 

oder

Die gesamte Funktion und ihre embeded Funktionen zum Beispiel:

function fn(){ 
    "use strict"; 
+0

Es gibt bereits eine akzeptierte Antwort, die das OP-Problem löst. Deines fügt keine Qualität mehr hinzu. –

Verwandte Themen