Cosa fa "usa rigoroso" in JavaScript e qual è il ragionamento alla base?


7549

Di recente, ho eseguito parte del mio codice JavaScript tramite JSLint di Crockford , e ha dato il seguente errore:

Problema alla riga 1 carattere 1: dichiarazione "usa rigorosa" mancante.

Facendo delle ricerche, mi sono reso conto che alcune persone aggiungono il "use strict";loro codice JavaScript. Dopo aver aggiunto la dichiarazione, l'errore ha smesso di apparire. Sfortunatamente, Google non ha rivelato gran parte della storia dietro questa affermazione di stringa. Certamente deve avere qualcosa a che fare con il modo in cui JavaScript viene interpretato dal browser, ma non ho idea di quale sarebbe l'effetto.

Quindi di cosa si "use strict";tratta, cosa implica ed è ancora rilevante?

Qualcuno dei browser attuali risponde alla "use strict";stringa o è per un uso futuro?


5
Le risposte qui sono vecchie ma sono sbagliate. Il ragionamento principale per la modalità rigorosa non era quello di prevenire errori di programmazione - era di rendere JavaScript con finalità lessicale in modo che potesse essere staticamente analizzabile:]
Benjamin Gruenbaum

@BenjaminGruenbaum L'uso "use strict";da solo non rende JS con ambito lessicale. Dichiarare variabili con lete constdovrebbero essere usate anche.
Koorosh Pasokhi,

Stai mescolando tra scoping a blocchi e scoping lessicale.
Benjamin Gruenbaum,

Risposte:


4938

Questo articolo sulla Javascript Strict Mode potrebbe interessarti: John Resig - ECMAScript 5 Strict Mode, JSON e altro

Per citare alcune parti interessanti:

La modalità Strict è una nuova funzionalità di ECMAScript 5 che consente di posizionare un programma o una funzione in un contesto operativo "rigoroso". Questo rigoroso contesto impedisce che vengano intraprese determinate azioni e genera ulteriori eccezioni.

E:

La modalità rigorosa aiuta in un paio di modi:

  • Cattura alcuni bloopers di codifica comuni, generando eccezioni.
  • Previene o genera errori quando vengono intraprese azioni relativamente "non sicure" (come ottenere l'accesso all'oggetto globale).
  • Disabilita le funzionalità che sono confuse o mal pensate.

Nota anche che puoi applicare la "modalità rigorosa" all'intero file ... O puoi usarla solo per una funzione specifica (citando ancora l'articolo di John Resig) :

// Non-strict code...

(function(){
  "use strict";

  // Define your library strictly...
})();

// Non-strict code... 

Il che potrebbe essere utile se devi mescolare codice vecchio e nuovo ;-)

Quindi, suppongo sia un po 'come "use strict"puoi usare in Perl (da qui il nome?) : Ti aiuta a fare meno errori, rilevando più cose che potrebbero portare a rotture.

La modalità Strict è ora supportata da tutti i principali browser .

All'interno dei moduli ECMAScript nativi (con importe exportdichiarazioni) e classi ES6 , strict mode è sempre abilitata e non può essere disabilitata.


100
Cambiare l'impostazione predefinita dopo così tanti anni? Troppo tardi: distruggerebbe così tanti siti / script / applicazioni esistenti ... L'unica cosa possibile è aiutare a migliorare le cose, per il futuro.
Pascal MARTIN

14
Ho provato un piccolo frammento di codice che non sarebbe valido quando si utilizza "use strict"Firefox 3.6, Safari 5, Chrome 7 e Opera 10.6 (tutti i Mac). Nessun errore, quindi immagino che "use strict" non sia ancora supportato in nessun browser. Non ho testato in IE9;)
Husky,

11
Aggiornamento rapido: Firefox 4 ha il supporto completo per la modalità rigorosa e, per quanto ne so, nessun altro browser lo fa. Safari e Chrome hanno un supporto "parziale", ma non so davvero cosa significhi.
Sasha Chedygov,

29
Chrome 11 sembra superare tutti questi test, così come IE10 ie.microsoft.com/testdrive/HTML5/TryStrict/Default.html#
gman,

12
@Julius - Questo non avrebbe potuto essere implementato usando una parola chiave riservata, perché il codice che cercava di attivare la modalità rigorosa avrebbe rotto nei vecchi browser. L'aggiunta di una stringa "casuale" letterale non rompe nulla.
nnnnnn,

1245

È una nuova funzionalità di ECMAScript 5. John Resig ne ha redatto un bel riassunto .

È solo una stringa che inserisci nei tuoi file JavaScript (nella parte superiore del file o all'interno di una funzione) che assomiglia a questo:

"use strict";

Inserirlo nel tuo codice ora non dovrebbe causare problemi con i browser attuali in quanto è solo una stringa. Potrebbe causare problemi con il codice in futuro se il codice viola il pragma. Ad esempio, se attualmente lo hai foo = "bar"senza fooprima definire , il tuo codice inizierà a fallire ... il che è una buona cosa secondo me.


329
Fallire velocemente e fallire ad alta voce.
Niels Bom,

31
Se stai scrivendo Javascript in linea nei file HTML, avvia ogni nuovo blocco con <script>"use strict";. Il flag si applica solo al blocco in cui è incluso.
nobar,

7
È divertente, questo ha comportato che le stringhe debbano avere virgolette singole. Quindi scrivi 'use strict';invece
nilsi il

1
allora cosa accadrebbe al concetto di sollevamento di JavaScript?
Sunil Sharma,

1
@SunilSharma Se provi a sollevare, ma fallisce perché la variabile non è definita, al momento la aggiungerà all'oggetto globale. Con "use strict";, invece fallirà. Questo ha più senso, perché se lo aggiunge all'oggetto globale significa che potrebbe non funzionare la prossima volta che si esegue la funzione / fare qualcos'altro che reimposta il blocco, poiché sarà nel blocco più alto (globale).
wizzwizz4,

646

La dichiarazione "use strict";indica al browser di utilizzare la modalità Strict, che è un set di funzioni ridotto e più sicuro di JavaScript.

Elenco delle funzionalità (non esaustivo)

  1. Non consente le variabili globali. (Cattura vardichiarazioni e errori di battitura mancanti nei nomi delle variabili)

  2. Le assegnazioni non riuscite silenziose generano errori in modalità rigorosa (assegnazione NaN = 5;)

  3. I tentativi di eliminare le proprietà non cancellabili genereranno ( delete Object.prototype)

  4. Richiede che tutti i nomi delle proprietà in un oggetto letterale siano univoci ( var x = {x1: "1", x1: "2"})

  5. I nomi dei parametri delle funzioni devono essere univoci ( function sum (x, x) {...})

  6. Vieta la sintassi ottale ( var x = 023;alcuni sviluppatori ritengono erroneamente che uno zero precedente non faccia nulla per cambiare il numero.)

  7. Vieta la withparola chiave

  8. eval in modalità rigorosa non introduce nuove variabili

  9. Vieta l'eliminazione dei nomi semplici ( delete x;)

  10. Vieta l'associazione o l'assegnazione dei nomi evale argumentsin qualsiasi forma

  11. La modalità Strict non alias le proprietà argumentsdell'oggetto con i parametri formali. (cioè in function sum (a,b) { return arguments[0] + b;}Questo funziona perché arguments[0]è legato a ae così via.)

  12. arguments.callee non è supportato

[Rif: modalità rigorosa , rete di sviluppatori Mozilla ]


40
Nit: le variabili globali sono consentite, devono solo essere esplicite (ad es window.foo = bar.).
gcampbell,

1
Richiede che tutti i nomi di proprietà in un oggetto letterale siano univoci (var x = {x1: "1", x1: "2"}) è valido
Arun Killu,

4
Nel tuo esempio in 11 manca una modifica di a (altrimenti non ha senso). I. e. somma delle funzioni (a, b) {a = 0; argomenti di ritorno [0] + b; } avviso (somma (1, 2)) restituirà 3 con modalità rigorosa e 2 senza modalità rigorosa, a causa dell'aliasing.
David Gausmann,

413

Se le persone sono preoccupate per l'uso use strict, vale la pena dare un'occhiata a questo articolo:

Supporto ECMAScript 5 "Modalità rigorosa" nei browser. Cosa significa questo?
NovoGeek.com - il blog di Krishna

Parla del supporto del browser, ma soprattutto come gestirlo in sicurezza:

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

116
Non sono d'accordo. Penso che questo dimostri perché è molto utile. In sostanza significa che questo ritorna alla sua funzione e non alwindow
Jamie Hutber il

36
quando mai vorresti la finestra con thiscui non puoi mirare window?
Jamie Hutber,

14
Si riferisce a se stesso. thisappartiene alla propria funzione e non alla finestra globale
Jamie Hutber,

26
Nel secondo thisuno è in realtà undefined.
Broxzier,

14
Il punto è che il tuo programma JS inizierà a fallire a causa dell'accesso a una proprietà di un indefinito, invece di fare silenziosamente la cosa sbagliata sull'oggetto globale. Rende molto più facile rintracciare i bug sottili.
Stephen Chung,

208

Un avvertimento, tutti programmatori che si stanno caricando a fondo: l'applicazione "use strict"al codice esistente può essere pericolosa! Questa cosa non è un adesivo per sentirsi bene, con la faccia felice che puoi schiaffeggiare sul codice per renderlo "migliore". Con il "use strict"pragma, il browser improvvisamente lancerà eccezioni in luoghi casuali che non ha mai lanciato prima solo perché in quel punto stai facendo qualcosa che JavaScript predefinito / sciolto consente felicemente ma aborrisce JavaScript rigorosamente! Potresti avere violazioni della rigidità che si nascondono nelle chiamate usate raramente nel tuo codice che genereranno un'eccezione solo quando alla fine vengono eseguite, ad esempio nell'ambiente di produzione che utilizzano i tuoi clienti paganti!

Se hai intenzione di fare il grande passo, è una buona idea applicare "use strict"insieme a test unitari completi e un'attività di build JSHint strettamente configurata che ti darà la certezza che non c'è angolo oscuro del tuo modulo che esploderà orribilmente solo perché tu ho attivato la modalità rigorosa. Oppure, ehi, ecco un'altra opzione: basta non aggiungere "use strict"alcun codice legacy, probabilmente è più sicuro in questo modo, onestamente. Sicuramente NON aggiungere "use strict"a moduli che non possiedi o mantieni, come i moduli di terze parti.

Penso che anche se è un animale in gabbia mortale, "use strict"può essere roba buona, ma devi farlo bene. Il momento migliore per essere severi è quando il tuo progetto è greenfield e stai iniziando da zero. Configura JSHint/JSLintcon tutti gli avvertimenti e le opzioni più serrati che la tua squadra può sopportare, ottieni un buon sistema di costruzione / test / asserzione come se fosse truccato Grunt+Karma+Chai, e solo allora inizi a contrassegnare tutti i tuoi nuovi moduli come "use strict". Preparati a curare molti errori e avvertimenti. Assicurati che tutti capiscano la gravità configurando la build su FAIL se si JSHint/JSLintverificano violazioni.

Il mio progetto non era un progetto greenfield quando l'ho adottato "use strict". Di conseguenza, il mio IDE è pieno di segni rossi perché non ho "use strict"sulla metà dei miei moduli e JSHint se ne lamenta. Mi ricorda ciò che refactoring dovrei fare in futuro. Il mio obiettivo è quello di essere libero dal segno rosso a causa di tutte le mie "use strict"dichiarazioni mancanti , ma sono passati anni.


24
PERCHÉ gli sviluppatori di questo thread sono così spericolati riguardo "usare rigorosamente" ?? GLI ECCEZIONI nel JavaScript altrimenti funzionante , per l'amor del cielo! Basta cospargerlo sul codice come zucchero su Corn Flakes, eh? NO! CATTIVO! "Usa rigoroso" dovrebbe essere usato con cautela, preferibilmente solo nel codice che controlli che ha unit test che passano contro tutti i principali browser e che esercitano tutti i percorsi del codice. Hai dei test? Va bene, "usare rigoroso" va bene per te, buttati fuori.
DWoldrich

57
Sì. Ovviamente "usa rigoroso" può rompere javascript apparentemente valido che non si è mai rotto prima. Ma il codice che non si è mai rotto prima non è uguale al codice corretto e che fa quello che dovrebbe. Solitamente fare riferimento a variabili non dichiarate segnala un errore di battitura, ecc. L'uso di stretto consente di rilevare questo tipo di errori, e si spera prima di spedire il codice di produzione.
Jostein Kjønigsen il

5
... o semplicemente applica "usa rigoroso" come parte di un ultimo passaggio sul tuo codice, risolvi tutti gli ovvi problemi, stringi le spalle, dì "abbastanza buono", quindi portalo fuori per la produzione :)
Wolfie Inu,

13
Personalmente, non aggiungo mai / molto raramente "use strict";al codice esistente. Detto questo, lo userò quasi sempre quando scriverò un nuovo codice da zero
Martin

3
Se stai già utilizzando JSLint, probabilmente hai risolto la maggior parte dei luoghi in cui "usare rigoroso" avrebbe rotto le cose, però.
Jonathan Cast

179

L'uso 'use strict';non migliora improvvisamente il codice.

La modalità rigorosa JavaScript è una funzionalità di ECMAScript 5 . Puoi abilitare la modalità rigorosa dichiarandola nella parte superiore del tuo script / funzione.

'use strict';

Quando un motore JavaScript vede questa direttiva , inizierà a interpretare il codice in una modalità speciale. In questa modalità, vengono rilevati errori quando vengono rilevate alcune pratiche di codifica che potrebbero diventare potenziali bug (che è il ragionamento alla base della modalità rigorosa).

Considera questo esempio:

var a = 365;
var b = 030;

Nella loro ossessione di allineare i letterali numerici, lo sviluppatore ha inavvertitamente inizializzato la variabile bcon un letterale ottale. La modalità non rigorosa interpreterà questo come un valore letterale numerico con valore 24(in base 10). Tuttavia, la modalità rigorosa genererà un errore.

Per un elenco non esaustivo di specialità in modalità rigorosa, vedere questa risposta .


Dove dovrei usare 'use strict';?

  • Nella mia nuova applicazione JavaScript: assolutamente! La modalità Strict può essere utilizzata come informatore quando stai facendo qualcosa di stupido con il tuo codice.

  • Nel mio codice JavaScript esistente : probabilmente no! Se il tuo codice JavaScript esistente ha dichiarazioni proibite in modalità rigorosa, l'applicazione si interromperà semplicemente. Se si desidera la modalità rigorosa, è necessario essere pronti a eseguire il debug e correggere il codice esistente. Questo è il motivo per cui l' utilizzo 'use strict';non migliora improvvisamente il codice .


Come si usa la modalità rigorosa?

  1. Inserisci una 'use strict';dichiarazione sopra il tuo script:

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

    Si noti che tutto nel file myscript.jsverrà interpretato in modalità rigorosa.

  2. Oppure, inserisci 'use strict';un'istruzione nella parte superiore del corpo della funzione:

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

    Tutto nell'ambito della funzione lessicaledoSomething verrà interpretato in modo rigoroso. La parola ambito lessicale è importante qui. Ad esempio, se il codice rigoroso chiama una funzione di una libreria non rigorosa , solo il codice viene eseguito in modalità rigorosa e non la funzione chiamata. Vedi questa risposta per una spiegazione migliore.


Quali cose sono vietate in modalità rigorosa?

Ho trovato un bell'articolo che descrive diverse cose proibite in modalità rigorosa (si noti che questo non è un elenco esclusivo):

Scopo

Storicamente, JavaScript è stato confuso su come le funzioni sono nell'ambito. A volte sembrano avere un ambito statico, ma alcune funzionalità li fanno comportare come se fossero con ambito dinamico. Questo è confuso, rendendo i programmi difficili da leggere e comprendere. L'incomprensione provoca bug. È anche un problema per le prestazioni. L'ambito statico consentirebbe che l'associazione variabile si verifichi in fase di compilazione, ma il requisito per l'ambito dinamico implica che l'associazione deve essere rinviata al tempo di esecuzione, che comporta una significativa penalizzazione delle prestazioni.

La modalità rigorosa richiede che tutta l'associazione delle variabili sia eseguita staticamente. Ciò significa che le funzioni che in precedenza richiedevano l'associazione dinamica devono essere eliminate o modificate. In particolare, l'istruzione with viene eliminata e la capacità della funzione eval di manomettere l'ambiente del suo chiamante è fortemente limitata.

Uno dei vantaggi del codice rigoroso è che strumenti come YUI Compressor possono fare un lavoro migliore durante l'elaborazione.

Variabili globali implicite

JavaScript ha implicato variabili globali. Se non dichiari esplicitamente una variabile, una variabile globale viene dichiarata implicitamente per te. Questo rende la programmazione più semplice per i principianti perché possono trascurare alcune delle loro faccende domestiche di base. Ma rende la gestione di programmi più grandi molto più difficile e degrada in modo significativo l'affidabilità. Pertanto, in modalità rigorosa, le variabili globali implicite non vengono più create. Dovresti dichiarare esplicitamente tutte le tue variabili.

Perdita globale

Esistono diverse situazioni che potrebbero causare this l'associazione all'oggetto globale. Ad esempio, se si dimentica di fornire il newprefisso quando si chiama una funzione di costruzione, quella di costruzione thisverrà associata inaspettatamente all'oggetto globale, quindi invece di inizializzare un nuovo oggetto, manometterà invece silenziosamente le variabili globali. In queste situazioni, la modalità rigorosa sarà invece legarsi thisa undefined, che causerà il costruttore un'eccezione invece, permettendo l'errore da rilevare molto prima.

Guasto rumoroso

JavaScript ha sempre avuto proprietà di sola lettura, ma non è stato possibile crearle da soli fino a quando la Object.createProperty funzione di ES5 non ha rivelato tale funzionalità. Se si tentasse di assegnare un valore a una proprietà di sola lettura, fallirebbe silenziosamente. L'assegnazione non cambierebbe il valore della proprietà, ma il programma procederà come se fosse. Questo è un rischio di integrità che può far sì che i programmi vadano in uno stato incoerente. In modalità rigorosa, il tentativo di modificare una proprietà di sola lettura genererà un'eccezione.

Octal

La rappresentazione dei numeri ottale (o base 8) era estremamente utile quando si eseguiva la programmazione a livello di macchina su macchine le cui dimensioni delle parole erano un multiplo di 3. Per lavorare con il mainframe CDC 6600, che aveva una dimensione delle parole di 60 bit, era necessario ottale. Se potessi leggere ottale, potresti guardare una parola di 20 cifre. Due cifre rappresentavano il codice operativo e una cifra identificava uno degli 8 registri. Durante la lenta transizione da codici macchina a linguaggi di alto livello, si riteneva utile fornire moduli ottali nei linguaggi di programmazione.

In C, è stata selezionata una rappresentazione estremamente sfortunata dell'ottalità: zero iniziale. Quindi in C, 0100significa 64, non 100, ed 08è un errore, non 8. Ancora più sfortunatamente, questo anacronismo è stato copiato in quasi tutti i linguaggi moderni, incluso JavaScript, dove viene utilizzato solo per creare errori. Non ha altro scopo. Quindi, in modalità rigorosa, le forme ottali non sono più consentite.

Eccetera

Gli argomenti pseudo array diventano un po 'più simili a array in ES5. In modalità rigorosa, perde le sue calleee caller proprietà. Questo rende possibile passare il tuo argumentscodice non attendibile senza rinunciare a molti contesti confidenziali. Inoltre, la argumentsproprietà delle funzioni viene eliminata.

In modalità rigorosa, i tasti duplicati in una funzione letterale produrranno un errore di sintassi. Una funzione non può avere due parametri con lo stesso nome. Una funzione non può avere una variabile con lo stesso nome di uno dei suoi parametri. Una funzione non può avere le deletesue variabili. Un tentativo su deleteuna proprietà non configurabile ora genera un'eccezione. I valori primitivi non sono implicitamente racchiusi.


Parole riservate per future versioni di JavaScript

ECMAScript 5 aggiunge un elenco di parole riservate. Se li usi come variabili o argomenti, la modalità rigorosa genererà un errore. Le parole riservate sono:

implements, interface, let, package, private, protected, public, static, Eyield


Ulteriori letture


2
è una spiegazione molto bella. Tuttavia, ho un dubbio che posso usare la modalità "rigorosa" insieme ad altre librerie di script Java, come Angular js?
UVM

3
@UVM: la direttiva sulla modalità rigorosa riguarda solo l'ambito lessicale. vale a dire solo il file / la funzione dichiarata. Se si dispone di un altro file / funzione che non ha la 'use strict'direttiva, verranno eseguiti in modalità non rigorosa, anche quando richiamati da una funzione in esecuzione in modalità rigorosa. Vedi questo asnwer per una spiegazione.
sampathsris,

Questo non è del tutto corretto. 'usa rigoroso' cambia il modo in cui il codice viene eseguito.
CyberEd,

3
Al secondo sguardo, hai ragione. Pensavo intendessi dire che generava solo delle eccezioni, ma non ha cambiato il modo in cui il codice ha funzionato (come cambiare this). Ora vedo che ti riferivi a chiamare altre funzioni.
CyberEd

3
Ci sono alcuni casi in cui l'ottale è utile. La sintassi C per questo è orribile, ma mi sarebbe piaciuto vedere le lingue aggiungere una nuova sintassi ottale che potrebbe quindi rendere obsoleta la forma zero iniziale. Naturalmente, per Javascript avere supportato la forma zero iniziale era semplicemente sciocco.
supercat

138

Consiglio vivamente a tutti gli sviluppatori di iniziare a utilizzare la modalità rigorosa ora. Ci sono abbastanza browser che lo supportano che la modalità rigorosa ci aiuterà legittimamente a salvarci da errori che non sapevamo nemmeno fossero nel tuo codice.

Apparentemente, nella fase iniziale ci saranno errori che non abbiamo mai riscontrato prima. Per ottenere il massimo beneficio, dobbiamo eseguire i test appropriati dopo essere passati alla modalità rigorosa per assicurarci di aver catturato tutto. Sicuramente non limitiamo a inserire il use strictnostro codice e supponiamo che non ci siano errori. Quindi il churn è che è ora di iniziare a usare questa funzionalità linguistica incredibilmente utile per scrivere codice migliore.

Per esempio,

var person = {
    name : 'xyz',
    position : 'abc',
    fullname : function () {  "use strict"; return this.name; }
};

JSLint è un debugger scritto da Douglas Crockford. Basta incollare lo script e scansionerà rapidamente per rilevare eventuali problemi evidenti ed errori nel codice.


6
@JamieHutber: visita questo link caniuse.com/use-strict AND kangax.github.io/es5-compat-table . Darà un'idea esatta per tutti i browser.
Pank

95

Vorrei offrire una risposta un po 'più fondata che integri le altre risposte. Speravo di modificare la risposta più popolare, ma non ci sono riuscito. Ho cercato di renderlo il più completo e completo possibile.

È possibile fare riferimento alla documentazione MDN per ulteriori informazioni.

"use strict" una direttiva introdotta in ECMAScript 5.

Le direttive sono simili alle dichiarazioni, ma diverse.

  • use strictnon contiene parole chiave: la direttiva è una semplice espressione expression, che consiste in una speciale stringa letterale (tra virgolette singole o doppie). I motori JavaScript, che non implementano ECMAScript 5, vedono semplicemente una dichiarazione di espressione senza effetti collaterali. Si prevede che le future versioni degli standard ECMAScript verranno introdotte usecome una vera parola chiave; le virgolette diventerebbero così obsolete.
  • use strictpuò essere usato solo all'inizio di uno script o di una funzione, cioè deve precedere ogni altra affermazione (reale). Non deve essere la prima istruzione in uno script di funzione: può essere preceduta da altre espressioni di istruzioni costituite da valori letterali di stringa (e le implementazioni JavaScript possono trattarle come direttive specifiche di implementazione). Le istruzioni letterali di stringa, che seguono una prima istruzione reale (in uno script o una funzione) sono semplici espressioni di espressione. Gli interpreti non devono interpretarli come direttive e non hanno alcun effetto.

La use strictdirettiva indica che il seguente codice (in uno script o una funzione) è un codice rigoroso. Il codice al livello più alto di uno script (codice che non è in una funzione) è considerato un codice rigoroso quando lo script contiene una use strictdirettiva. Il contenuto di una funzione è considerato un codice rigoroso quando la funzione stessa è definita in un codice rigoroso o quando la funzione contiene una use strictdirettiva. Il codice che viene passato a un eval()metodo è considerato un codice rigoroso quando è eval()stato chiamato da un codice rigoroso o contiene la use strictdirettiva stessa.

La modalità rigorosa di ECMAScript 5 è un sottoinsieme limitato del linguaggio JavaScript, che elimina i deficit rilevanti della lingua e presenta un controllo degli errori più rigoroso e una maggiore sicurezza. Di seguito sono elencate le differenze tra la modalità rigorosa e la modalità normale (di cui i primi tre sono particolarmente importanti):

  • Non è possibile utilizzare with-statement in modalità rigorosa.
  • In modalità rigorosa devono essere dichiarate tutte le variabili: se si assegna un valore a un identificatore che non è stato dichiarato come variabile, funzione, parametro della funzione, parametro della clausola di cattura o proprietà del globale Object, si otterrà un ReferenceError. In modalità normale l'identificatore viene implicitamente dichiarato come variabile globale (come proprietà del globale Object)
  • In modalità rigorosa la parola chiave thisha il valore undefinednelle funzioni che sono state invocate come funzioni (non come metodi). (In modalità normale thispunta sempre al globale Object). Questa differenza può essere utilizzata per verificare se un'implementazione supporta la modalità rigorosa:
var hasStrictMode = (function() { "use strict"; return this===undefined }());
  • Anche quando una funzione viene invocata con call()o applyin modalità rigorosa, allora thisè esattamente il valore del primo argomento della chiamata call()o apply(). (In modalità normale nulle undefinedvengono sostituiti dal globale Objecte i valori, che non sono oggetti, vengono espressi in oggetti.)

  • In modalità rigorosa otterrai un TypeError, quando provi ad assegnare a proprietà di sola lettura o a definire nuove proprietà per un oggetto non estensibile. (In modalità normale entrambi falliscono semplicemente senza messaggio di errore.)

  • In modalità rigorosa, quando si passa il codice a eval(), non è possibile dichiarare o definire variabili o funzioni nell'ambito del chiamante (come è possibile farlo in modalità normale). Invece, viene creato un nuovo ambito per eval()e le variabili e le funzioni rientrano in tale ambito. Tale ambito viene distrutto al eval()termine dell'esecuzione.
  • In modalità rigorosa, l'oggetto-argomento di una funzione contiene una copia statica dei valori, che vengono passati a quella funzione. Nella modalità normale l'oggetto argomenti ha un comportamento un po '"magico": gli elementi dell'array e i parametri della funzione denominata fanno riferimento allo stesso valore.
  • In modalità rigorosa otterrai un punto SyntaxErrorquando l' deleteoperatore è seguito da un identificatore non qualificato (una variabile, funzione o parametro di funzione). In modalità normale l' deleteespressione non farebbe nulla e viene valutata false.
  • In modalità rigorosa, otterrai un messaggio TypeErrorquando provi a eliminare una proprietà non configurabile. (In modalità normale il tentativo fallisce semplicemente e deleteviene valutata l' espressione false).
  • In modalità rigorosa viene considerato un errore sintattico quando si tenta di definire più proprietà con lo stesso nome per un oggetto letterale. (In modalità normale non c'è errore.)
  • In modalità rigorosa viene considerato un errore sintattico quando una dichiarazione di funzione ha più parametri con lo stesso nome. (In modalità normale non c'è errore.)
  • In modalità rigorosa non sono consentiti letterali ottali (sono letterali che iniziano con 0x. (In modalità normale alcune implementazioni consentono letterali ottali).
  • In modalità rigorosa gli identificatori evale argumentsvengono trattati come parole chiave. Non è possibile modificarne il valore, non è possibile assegnare loro un valore e non è possibile utilizzarli come nomi per variabili, funzioni, parametri di funzione o identificatori di un blocco catch.
  • In modalità rigorosa ci sono più restrizioni sulle possibilità di esaminare lo stack di chiamate. arguments.callere arguments.calleecausare a TypeErrorin una funzione in modalità rigorosa. Inoltre, alcune proprietà del chiamante e degli argomenti delle funzioni in modalità rigorosa causano un TypeErrorquando si tenta di leggerle.

4
"In modalità rigorosa non sono ammessi letterali ottali (sono letterali che iniziano con 0x ...)" I letterali ottali iniziano con un vantaggio 0.
Alex Gittemeier,

83

I miei due centesimi:

Uno degli obiettivi della modalità rigorosa è consentire un debug più rapido dei problemi. Aiuta gli sviluppatori lanciando un'eccezione quando si verificano determinate cose sbagliate che possono causare un comportamento silenzioso e strano della tua pagina web. Nel momento in cui usiamo use strict, il codice genererà errori che aiutano lo sviluppatore a risolverlo in anticipo.

Poche cose importanti che ho imparato dopo aver usato use strict:

Previene la dichiarazione delle variabili globali:

var tree1Data = { name: 'Banana Tree',age: 100,leafCount: 100000};

function Tree(typeOfTree) {
    var age;
    var leafCount;

    age = typeOfTree.age;
    leafCount = typeOfTree.leafCount;
    nameoftree = typeOfTree.name;
};

var tree1 = new Tree(tree1Data);
console.log(window);

Ora, questo codice crea nameoftreein ambito globale a cui è possibile accedere utilizzando window.nameoftree. Quando implementiamo use strictil codice genererebbe un errore.

Errore di riferimento non rilevato: nameoftree non è definito

Sample

Elimina la withdichiarazione:

withle istruzioni non possono essere minimizzate usando strumenti come uglify-js . Sono inoltre deprecati e rimossi dalle future versioni di JavaScript.

Sample

Previene i duplicati:

Quando abbiamo una proprietà duplicata, genera un'eccezione

Uncaught SyntaxError: proprietà duplicata dei dati nell'oggetto letterale non consentita in modalità rigorosa

"use strict";
var tree1Data = {
    name: 'Banana Tree',
    age: 100,
    leafCount: 100000,
    name:'Banana Tree'
};

Ci sono pochi altri, ma ho bisogno di acquisire maggiori conoscenze al riguardo.


Con ECMAScript 2015 sono consentiti nuovamente nomi di proprietà duplicati! Vedi la documentazione MDN .
Philmcole,

62

Se usi un browser rilasciato nell'ultimo anno o giù di lì, molto probabilmente supporta la modalità Strict JavaScript. Solo i browser più vecchi in circolazione prima che ECMAScript 5 diventasse lo standard attuale non lo supportano.

Le virgolette intorno al comando assicurano che il codice continuerà a funzionare anche nei browser più vecchi (anche se le cose che generano un errore di sintassi in modalità rigorosa in genere causano un malfunzionamento dello script in qualche modo difficile da rilevare in quei browser più vecchi).


12
Allora cosa fa?
Anish Gupta,

7
... questo descrive in parte la compatibilità, ma non ciò che effettivamente fa.
courtimas,

58

Quando si aggiungono "use strict";, i seguenti casi generano un SyntaxError prima dell'esecuzione dello script:

  • Preparare il terreno per le future versioni ECMAScript , utilizzando una delle parole chiave di nuova riservate (in previsione per ECMAScript 6 ): implements, interface, let, package, private, protected, public, static, e yield.

  • Funzione di dichiarazione in blocchi

    if(a<b){ function f(){} }
  • Sintassi ottale

    var n = 023;
  • this puntare all'oggetto globale.

     function f() {
          "use strict";
          this.a = 1;
     };
     f(); 
  • Dichiarare due volte lo stesso nome per un nome di proprietà in un oggetto letterale

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

    Questo non è più il caso in ECMAScript 6 ( bug 1041128 ).

  • Dichiarazione di due argomenti di funzione con la stessa funzione di nome

    f(a, b, b){}
  • Impostazione di un valore su una variabile non dichiarata

    function f(x){
       "use strict";
       var a = 12;
       b = a + x*35; // error!
    }
    f();
  • Usando deletesu un nome di variabiledelete myVariable;

  • Utilizzo evalo argumentscome nome dell'argomento variabile o funzione

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

fonti:


Con ECMAScript 2015 sono consentiti nuovamente nomi di proprietà duplicati! Vedi la documentazione MDN .
Philmcole,

53

La modalità rigorosa apporta diverse modifiche alla normale semantica JavaScript:

  • elimina alcuni errori silenziosi JavaScript modificandoli per generare errori.

  • corregge errori che rendono difficile per i motori JavaScript eseguire ottimizzazioni.

  • vieta alcune sintassi che potrebbero essere definite nelle versioni future di ECMAScript.

per maggiori informazioni visita la modalità Strict-Javascript


52

"Usa rigoroso"; è un'assicurazione che il programmatore non utilizzerà le proprietà sciolte o cattive di JavaScript. È una guida, proprio come un righello ti aiuterà a fare linee rette. "Usa rigoroso" ti aiuterà a fare "codifica diretta".

Quelli che preferiscono non usare i righelli per fare le righe in linea di solito finiscono in quelle pagine che chiedono ad altri di eseguire il debug del loro codice.

Credimi. Il sovraccarico è trascurabile rispetto al codice mal progettato. Doug Crockford, che è stato uno sviluppatore JavaScript senior per diversi anni, ha un post molto interessante qui . Personalmente, mi piace tornare sempre sul suo sito per essere sicuro di non dimenticare le mie buone pratiche.

La moderna pratica JavaScript dovrebbe sempre evocare "Usa rigoroso"; pragma. L'unico motivo per cui il gruppo ECMA ha reso facoltativa la modalità "Rigorosa" è consentire a programmatori meno esperti di accedere a JavaScript e dare quindi il tempo di adattarsi alle nuove e più sicure pratiche di codifica.


66
La ragione per cui la modalità rigorosa è facoltativa non ha nulla a che fare con ciò che hai affermato. Il vero motivo è di non violare il codice esistente che potrebbe non essere conforme .
Dexygen

17
In effetti, i programmatori meno esperti dovrebbero essere i primi a consentire l '"uso rigoroso";
Antti Haapala,

46

Includere use strictall'inizio di tutti i tuoi file JavaScript sensibili da questo punto è un piccolo modo per essere un programmatore JavaScript migliore ed evitare che le variabili casuali diventino globali e le cose cambino silenziosamente.


42

Citando da w3schools :

La direttiva "usare rigorosamente"

La direttiva "usa rigoroso" è nuova in JavaScript 1.8.5 (ECMAScript versione 5).

Non è un'affermazione, ma un'espressione letterale, ignorata dalle versioni precedenti di JavaScript.

Lo scopo di "usa rigoroso" è di indicare che il codice deve essere eseguito in "modalità rigorosa".

Con la modalità rigorosa, ad esempio, non è possibile utilizzare variabili non dichiarate.

Perché la modalità rigorosa?

La modalità rigorosa semplifica la scrittura di JavaScript "sicuro".

La modalità rigorosa modifica la "sintassi errata" precedentemente accettata in errori reali.

Ad esempio, in JavaScript normale, la digitazione errata di un nome di variabile crea una nuova variabile globale. In modalità rigorosa, ciò genererà un errore, rendendo impossibile la creazione accidentale di una variabile globale.

In JavaScript normale, uno sviluppatore non riceverà alcun feedback di errore assegnando valori a proprietà non scrivibili.

In modalità rigorosa, qualsiasi assegnazione a una proprietà non scrivibile, una proprietà solo getter, una proprietà inesistente, una variabile inesistente o un oggetto inesistente genererà un errore.

Si prega di fare riferimento al http://www.w3schools.com/js/js_strict.asp sapere di più


37

"use strict"fa eseguire il codice JavaScript in modalità rigorosa , il che significa sostanzialmente che tutto deve essere definito prima dell'uso. Il motivo principale per l'utilizzo della modalità rigorosa è evitare usi globali accidentali di metodi non definiti.

Anche in modalità rigorosa, le cose corrono più velocemente, alcuni avvisi o avvisi silenziosi generano errori fatali, è meglio usarlo sempre per creare un codice più ordinato.

"use strict"è ampiamente necessario per essere utilizzato in ECMA5, in ECMA6 fa parte di JavaScript per impostazione predefinita , quindi non è necessario aggiungerlo se si utilizza ES6.

Guarda queste dichiarazioni ed esempi da MDN:

La direttiva "Usa rigorosa"
La direttiva "Usa rigorosa" è una novità di JavaScript 1.8.5 (ECMAScript versione 5). Non è un'affermazione, ma un'espressione letterale, ignorata dalle versioni precedenti di JavaScript. Lo scopo di "usa rigoroso" è di indicare che il codice deve essere eseguito in "modalità rigorosa". Con la modalità rigorosa, ad esempio, non è possibile utilizzare variabili non dichiarate.

Esempi di utilizzo di "Usa rigoroso":
Modalità rigorosa per le funzioni: Allo stesso modo, per invocare la modalità rigorosa per una funzione, inserisci la frase esatta "usa rigoroso"; (o "usa rigoroso";) nel corpo della funzione prima di qualsiasi altra affermazione.

1) modalità rigorosa nelle funzioni

 function strict() {
     // Function-level strict mode syntax
     'use strict';
     function nested() { return 'And so am I!'; }
     return "Hi!  I'm a strict mode function!  " + nested();
 }
 function notStrict() { return "I'm not strict."; }

 console.log(strict(), notStrict());

2) modalità rigorosa a tutto script

'use strict';
var v = "Hi! I'm a strict mode script!";
console.log(v);

3) Assegnazione a un globale non scrivibile

'use strict';

// Assignment to a non-writable global
var undefined = 5; // throws a TypeError
var Infinity = 5; // throws a TypeError

// Assignment to a non-writable property
var obj1 = {};
Object.defineProperty(obj1, 'x', { value: 42, writable: false });
obj1.x = 9; // throws a TypeError

// Assignment to a getter-only property
var obj2 = { get x() { return 17; } };
obj2.x = 5; // throws a TypeError

// Assignment to a new property on a non-extensible object.
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = 'ohai'; // throws a TypeError

Puoi leggere di più su MDN .


31

C'è un bel discorso da parte di alcune persone che facevano parte del comitato ECMAScript: modifiche a JavaScript, parte 1: ECMAScript 5 " su come l'uso incrementale dello "use strict"switch consente agli implementatori JavaScript di ripulire molte delle pericolose funzionalità di JavaScript senza interrompere improvvisamente ogni sito Web nel mondo.

Ovviamente parla anche di quante di queste malfunzionamenti sono (e) e di come ECMAScript 5 le risolve.


27

Piccoli esempi da confrontare:

Modalità non rigorosa:

for (i of [1,2,3]) console.log(i)
    
// output:
// 1
// 2
// 3

Modalità rigorosa:

'use strict';
for (i of [1,2,3]) console.log(i)

// output:
// Uncaught ReferenceError: i is not defined

Modalità non rigorosa:

String.prototype.test = function () {
  console.log(typeof this === 'string');
};

'a'.test();

// output
// false

String.prototype.test = function () {
  'use strict';
  
  console.log(typeof this === 'string');
};

'a'.test();

// output
// true


2
Si noti che il codice di cui sopra si aggiunge la ho variabile per la portata globale (in genere questo non è una best practice e modalità rigorosa aiuta ad evitare che).
michael

1
Qualcuno può spiegare il secondo esempio? Non capisco Non dovrebbe this === 'a'in entrambi gli esempi?
MaximeW

19

Si noti che è use strictstato introdotto in EcmaScript 5 e da allora è stato mantenuto.

Di seguito sono riportate le condizioni per attivare la modalità rigorosa in ES6 ed ES7 :

  • Il codice globale è un codice di modalità rigoroso se inizia con un prologo della direttiva che contiene una direttiva rigorosa sull'uso (vedere 14.1.1).
  • Il codice del modulo è sempre un codice di modalità rigoroso.
  • Tutte le parti di una ClassDeclaration o ClassExpression sono codici in modalità rigorosa.
  • Il codice di valutazione è un codice di modalità rigoroso se inizia con un prologo della direttiva che contiene una direttiva di utilizzo rigoroso o se la chiamata a valutazione è una valutazione diretta (vedere 12.3.4.1) contenuta nel codice di modalità rigorosa.
  • Il codice funzione è un codice di modalità rigoroso se la funzione FunctionDeclaration, FunctionExpression, GeneratorDeclaration, GeneratorExpression, MethodDefinition o ArrowFunction associata è contenuta nel codice di modalità rigorosa o se il codice che produce il valore dello slot interno [[ECMAScriptCode]] della funzione inizia con un prologo della direttiva che contiene una Direttiva sull'uso rigoroso.
  • Il codice funzione che viene fornito come argomento ai costruttori di funzioni e generatori integrati è un codice di modalità rigoroso se l'ultimo argomento è una stringa che, quando elaborata, è un corpo funzione che inizia con un prologo della direttiva che contiene una direttiva rigorosa d'uso.

14

I motivi principali per cui gli sviluppatori dovrebbero utilizzare "use strict"sono:

  1. Previene la dichiarazione accidentale di variabili globali . L'uso "use strict()"farà in modo che le variabili vengano dichiarate varprima dell'uso. Per esempio:

    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: la "use strict"direttiva è riconosciuta solo all'inizio di uno script o di una funzione.
  3. La stringa "arguments"non può essere utilizzata come variabile:

    "use strict";
    var arguments = 3.14;    // This will cause an error
  4. Limita l'uso delle parole chiave come variabili. Cercare di usarli genererà errori.

In breve, renderai il tuo codice meno soggetto a errori e, a sua volta, ti farà scrivere un buon codice.

Per saperne di più puoi consultare qui .


12

"usa rigoroso"; è lo sforzo dell'ECMA per rendere JavaScript un po 'più robusto. Porta in JS un tentativo di renderlo almeno un po '"rigoroso" (altre lingue applicano regole rigorose dagli anni '90). In realtà "costringe" gli sviluppatori JavaScript a seguire una sorta di best practice di codifica. Tuttavia, JavaScript è molto fragile. Non esistono variabili tipizzate, metodi digitati, ecc. Consiglio vivamente agli sviluppatori JavaScript di apprendere un linguaggio più solido come Java o ActionScript3 e di implementare le stesse best practice nel codice JavaScript, funzionerà meglio e sarà più facile debug.


12

La modalità JavaScript "rigorosa" è stata introdotta in ECMAScript 5.

(function() {
  "use strict";
  your code...
})();

La scrittura "use strict";nella parte superiore del file JS attiva un rigoroso controllo della sintassi. Fa per noi i seguenti compiti:

  1. mostra un errore se si tenta di assegnare a una variabile non dichiarata

  2. ti impedisce di sovrascrivere le principali librerie di sistema JS

  3. vieta alcune funzionalità del linguaggio non sicure o soggette a errori

use strictfunziona anche all'interno di singole funzioni. È sempre consigliabile includere use strictnel codice.

Problema di compatibilità del browser: le direttive "use" devono essere compatibili con le versioni precedenti. I browser che non li supportano vedranno solo una stringa letterale a cui non si fa più riferimento. Quindi, lo passeranno sopra e andranno avanti.


12

use strictè un modo per rendere il tuo codice più sicuro, perché non puoi utilizzare funzionalità pericolose che non possono funzionare come previsto. E, come è stato scritto prima, rende il codice più rigoroso.


11

Usa Strict viene utilizzato per mostrare errori comuni e ripetuti in modo che sia gestito in modo diverso e cambi il modo in cui viene eseguito lo script java, tali cambiamenti sono:

  • Previene i globuli accidentali

  • Nessun duplicato

  • Elimina con

  • Elimina questa coercizione

  • Safer eval ()

  • Errori per immutabili

puoi anche leggere questo articolo per i dettagli


11

Normalmente JavaScript non segue regole rigide, quindi aumenta la possibilità di errori. Dopo l'uso "use strict", il codice JavaScript dovrebbe seguire una rigida serie di regole come in altri linguaggi di programmazione come l'uso di terminatori, la dichiarazione prima dell'inizializzazione, ecc.

Se "use strict"viene utilizzato, il codice deve essere scritto seguendo una rigida serie di regole, riducendo quindi le possibilità di errori e ambiguità.


7

"usa rigoroso"; Definisce che il codice JavaScript deve essere eseguito in "modalità rigorosa".

  • La direttiva "usa rigoroso" era nuova in ECMAScript versione 5.
  • Non è un'affermazione, ma un'espressione letterale, ignorata dalle versioni precedenti di JavaScript.
  • Lo scopo di "usa rigoroso" è di indicare che il codice deve essere eseguito in "modalità rigorosa".
  • Con la modalità rigorosa, ad esempio, non è possibile utilizzare variabili non dichiarate.

Tutti i browser moderni supportano "usare rigorosamente" tranne Internet Explorer 9 e versioni precedenti .

Svantaggio

Se uno sviluppatore utilizzava una libreria in modalità rigorosa, ma lo sviluppatore era abituato a lavorare in modalità normale, potrebbe chiamare alcune azioni sulla libreria che non funzionavano come previsto.

Peggio ancora, dal momento che lo sviluppatore è in modalità normale, non ha i vantaggi di generare ulteriori errori, quindi l'errore potrebbe fallire silenziosamente.

Inoltre, come elencato sopra, la modalità rigorosa ti impedisce di fare determinate cose.

Le persone generalmente pensano che non dovresti usare queste cose in primo luogo, ma ad alcuni sviluppatori non piace il vincolo e vogliono usare tutte le funzionalità del linguaggio.


4

La modalità rigorosa può prevenire perdite di memoria.

Si prega di controllare la seguente funzione scritta in modalità non rigorosa:

function getname(){
    name = "Stack Overflow"; // Not using var keyword
    return name;
}
getname();
console.log(name); // Stack Overflow

In questa funzione, stiamo usando una variabile chiamata nameall'interno della funzione. Internamente, il compilatore verificherà prima se ci sono variabili dichiarate con quel nome specifico in quel particolare ambito di funzione. Dal momento che il compilatore ha capito che non esiste una tale variabile, controllerà l'ambito esterno. Nel nostro caso, è l'ambito globale. Ancora una volta, il compilatore ha capito che non esiste alcuna variabile dichiarata nello spazio globale con quel nome, quindi crea una tale variabile per noi nello spazio globale. Concettualmente, questa variabile verrà creata nell'ambito globale e sarà disponibile nell'intera applicazione.

Un altro scenario è che, diciamo, la variabile è dichiarata in una funzione figlio. In tal caso, il compilatore verifica la validità di quella variabile nell'ambito esterno, ovvero la funzione padre. Solo allora controllerà lo spazio globale e creerà una variabile per noi lì. Ciò significa che è necessario effettuare ulteriori controlli. Ciò influirà sulle prestazioni dell'applicazione.


Ora scriviamo la stessa funzione in modalità rigorosa.

"use strict"
function getname(){
    name = "Stack Overflow"; // Not using var keyword
    return name;
}
getname();
console.log(name); 

Otterremo il seguente errore.

Uncaught ReferenceError: name is not defined
at getname (<anonymous>:3:15)
at <anonymous>:6:5

Qui, il compilatore genera l'errore di riferimento. In modalità rigorosa, il compilatore non ci consente di utilizzare la variabile senza dichiararla. In questo modo è possibile prevenire perdite di memoria. Inoltre, possiamo scrivere codice più ottimizzato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.