2010-02-26 12 views
39

Quale ambito ha il pragma della modalità strict in ECMAScript5?In ECMAScript5, qual è lo scopo di "use strict"?

"use strict"; 

mi piacerebbe fare questo (soprattutto perché JSLint non si lamenta a questo proposito):

"use strict"; 

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

Ma io non sono sicuro se questo sarebbe rompere altro codice o meno. So che posso fare questo, che sarà portata il pragma alla funzione ...

(function() { 

    "use strict"; 

    // my stuff here... 

}()); 

ma JSLint lamenta (quando l'opzione JSLint "rigorosa" è abilitato), perché crede che tu stia l'esecuzione di codice prima di abilitare "use strict".

Ecco la mia domanda. Se ho fileA.js:

"use strict"; 
// do some stuff 

e fileB.js:

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

e poi li includo nella mia pagina html in questo stesso ordine, sarà il pragma essere ambito al file, o la volontà il pragma si perde nel file B, bloccando così l'esecuzione di eval?

+0

lato A nota: la presentazione di Douglad Crockford su "Lo stato e il futuro di Javascript è stata davvero eccezionale. Discute alcune delle nuove funzionalità come rigoroso alla fine del discorso. Ecco il link: http://www.infoq.com/presentations/The-State-and-Future-of-JavaScript –

+0

'eval()' è permesso con '" use strict "', viene appena applicato a livello globale. –

risposta

2

EDIT Sembra che non sia corretto. Si prega di consultare Jeff Walden's answer below.

Partenza questa risposta a una domanda relativa: What does "use strict" do in JavaScript, and what is the reasoning behind it?

Nonostante le lamentele di JSLint, si può (e dovrebbe ) utilizzare "use strict"; all'interno di una funzione se desideri solo che funzione sia in modalità rigorosa. Se lo si utilizza nel contesto globale, forzerà tutto il codice a essere in modalità rigorosa. Risposta breve: sì, bloccherà l'uso di eval.

+2

Questa risposta non è corretta. L'uso della direttiva nella parte superiore di 'fileA.js' fa sì che l'intero file sia in modalità rigorosa, ma non causa il fatto che' fileB.js' sia in modalità rigorosa, indipendentemente dall'ordine in cui sono inclusi nella pagina HTML . Inoltre, 'eval()' funziona in modo diverso in modalità rigorosa, ma funziona comunque. Non è "bloccato". –

54

"use strict" si applica solo alla funzione o all'ambito del programma. Quindi se hai fileA.js con "use strict" nella parte superiore, fileA.js viene eseguito in modalità rigorosa e tutte le funzioni definite in esso eseguiranno lo stesso quando vengono chiamate. Ma fileB.js è un programma separato, quindi lo "use strict" da fileA.js non si applica ad esso - e quindi fileB.js verrà eseguito in modalità non rigida. (Naturalmente, se somecodesnippet inizia con una direttiva "use strict" e analizza correttamente, quel codice verrà eseguito in modalità rigorosa e le funzioni definite da quel codice funzioneranno allo stesso modo.) La rigidità non è assolutamente "sanguinante" - e per ES5 4.2.2 (dichiaratamente non-normativo, ma sono sicuro di poter ricavare un riferimento normativo per questo, se necessario), "un'implementazione deve supportare la combinazione di unità di codice modalità illimitate e rigorose in un singolo programma composito".

Un getchack di questo: se si utilizza la modalità rigorosa nell'ambito globale a volte ma non sempre, non è più possibile concatenare gli script in un singolo file. Supponiamo di avere gli script A, B, C, D in questo ordine. Se A è severo, la concatenazione generale sarà rigorosa, anche se B/C/D non lo fosse! Viceversa, se A non è severo (e non è vuoto), la concatenazione generale sarà non rigida, anche se B/C/D sono rigidi. Questo ha già morso almeno un sito di early-adopter là fuori.

Detto questo, la modalità rigorosa non proibisce eval.Quando eval viene chiamato nella modalità normale in modalità rigorosa, utilizzando la sintassi del programma eval(code [, ...]), si tratta di un'evid "diretta" che si comporta nel modo in cui ha sempre eval - ad eccezione del fatto che code viene sempre valutato come codice a modalità rigorosa, anche se code non funziona t iniziare con una direttiva "use strict" e ad eccezione del fatto che qualsiasi variabile creata dal codice viene mantenuta nella propria memoria separata da qualsiasi variabile esistente. (La semantica esatta è un po 'complicata, lavoro sul motore JavaScript di Firefox, di recente implementare questa roba, e anche dopo una discreta quantità di tempo nello spec e lavorando su un'implementazione non è ancora intuitivo.)

Se non viene chiamato in questo modo: eval.call(...), setTimeout(eval, ...), setInterval(eval, ...), var ev = eval; ev(...); e così via, è una valutazione "indiretta". La valutazione indiretta (sia all'interno che all'esterno della modalità rigorosa) si comporta in modo leggermente diverso: la risoluzione dei nomi e la definizione delle variabili si verificano come se fossero nell'ambito globale. (Il codice verrà eseguito come codice della modalità rigorosa solo se inizia con una direttiva "use strict".)

Il supporto della modalità rigorosa è quasi - ma non completamente completato nell'ultimo Firefox nightlies, quindi potrebbe valerne la pena scaricarne uno per giocare in giro con quelle parti della modalità rigorosa che vengono implementate. Continuo a dire di tenere a bada l'uso della produzione fino a quando non è completo, ma è sicuramente pronto per la sperimentazione (a patto che tu capisca che la modalità rigorosa non è ancora completamente inserita). (Per quanto riguarda il collegamento di Sean McMillan, sappi che le sue affermazioni di "supporto" rappresentano l'estremo minimo di funzionalità necessario per ciascun proiettile. I test in modalità rigorosa sono molto migliori, anche se per essere sicuri che non sono affatto vicini a coprire completamente la modalità rigorosa.)

+4

'Strictness assolutamente non "sanguina"' - Questo non è del tutto corretto. Non è possibile utilizzare '.caller' in un codice non rigido quando la funzione su cui si utilizza è stata definita in modalità rigorosa. In questo modo il codice non rigoroso può infatti interrompersi a causa del fatto che altri codici sono in modalità rigorosa: considererei il sanguinamento. – AndreKR

+1

Il modo in cui è stata formulata la domanda originale, interpreterei "bleed" nel senso lessicale, testuale del codice sorgente - dello script B che prende rigore dallo script A, senza che B opti in rigorosità. Ovviamente, gli effetti di uno script (compresi quelli causati dalla severità) sono visibili - "bleed", si potrebbe dire - in altri script.La * natura * dell'effetto può variare a seconda della severità dello script di attivazione. Ma rigoroso o no, gli effetti di uno script sono visibili nell'altro. Non mi sembra una definizione particolarmente utile di "sanguinare". –

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

Non se in precedenza si dichiara somecodesnippet.

var somecodesnippet = "your awesome codesnippet here";

eval (somecodesnippet); // non respinto da "use strict"

0

L'intero file:

<script...> 
    "use strict"; 

o

L'intera funzione e le sue funzioni embeded ad esempio:

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

Esiste già una risposta accettata, che risolve il problema dell'OP. La tua non aggiunge più qualità. –