'; angularjs Che cosa fa "use strict" in JavaScript e qual è il ragionamento che sta dietro?




12 Answers

È una nuova funzionalità di ECMAScript 5. John Resig ha scritto un bel riassunto di questo.

È solo una stringa che inserisci nei tuoi file JavaScript (nella parte superiore del tuo 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. Potrebbero causare problemi con il tuo codice in futuro se il tuo codice violasse il pragma. Ad esempio, se al momento hai foo = "bar" senza prima definire foo , il tuo codice inizierà a fallire ... il che è una buona cosa secondo me.

strict mode javascript

Recentemente, ho eseguito un po 'del mio codice JavaScript tramite JSLint di Crockford, e ha dato il seguente errore:

Problema alla riga 1 carattere 1: manca la frase "use strict".

Facendo qualche ricerca, ho capito che alcune persone aggiungono "use strict"; nel loro codice JavaScript. Una volta aggiunta la dichiarazione, l'errore ha smesso di apparire. Sfortunatamente, Google non ha rivelato gran parte della storia dietro questa dichiarazione di stringa. Certamente deve avere qualcosa a che fare con il modo in cui il JavaScript viene interpretato dal browser, ma non ho idea di quale sarebbe l'effetto.

Quindi cos'è "use strict"; tutto ciò, cosa implica, ed è ancora rilevante?

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




Se le persone sono preoccupate use strict potrebbe valere la pena di dare un'occhiata a questo articolo:

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

Parla del supporto del browser, ma soprattutto di 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.
*/



Usare 'use strict'; improvvisamente non migliora il tuo codice.

La modalità rigorosa JavaScript è una funzionalità di ECMAScript 5 . Puoi attivare 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à, gli errori vengono generati quando determinate pratiche di codifica che potrebbero finire per essere individuate da potenziali bug vengono rilevate (che è il ragionamento alla base della modalità rigorosa).

Considera questo esempio:

var a = 365;
var b = 030;

Nella loro ossessione di allineare i valori letterali numerici, lo sviluppatore ha inavvertitamente inizializzato la variabile b con un valore letterale ottale. La modalità non rigida 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à rigorosa può essere utilizzata come informatore quando stai facendo qualcosa di stupido con il tuo codice.

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

Come uso la modalità rigorosa?

  1. Inserisci un 'use strict'; dichiarazione in cima al tuo script:

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

    Nota che tutto nel file myscript.js sarà interpretato in modalità rigorosa.

  2. Oppure, inserire un 'use strict'; dichiarazione in cima al tuo corpo della funzione:

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

    Tutto nella portata lessicale della funzione doSomething sarà interpretato in modalità rigorosa. La parola portata lessicale è importante qui. Vedi questa risposta per una spiegazione migliore.

Quali cose sono proibite in modalità rigorosa?

Ho trovato un buon articolo che descrive diverse cose che sono vietate in modalità rigorosa (si noti che questo non è un elenco esclusivo):

Scopo

Storicamente, JavaScript è stato confuso su come le funzioni sono scoped. A volte sembrano essere stati esaminati in modo statico, ma alcune funzioni li fanno comportare come se fossero a livello dinamico. Ciò è fonte di confusione, rendendo i programmi difficili da leggere e capire. L'incomprensione causa bug. È anche un problema per le prestazioni. L'ambito statico consentirebbe il binding variabile in tempo di compilazione, ma il requisito per l'ambito dinamico significa che l'associazione deve essere posticipata al runtime, che comporta una significativa riduzione delle prestazioni.

La modalità rigorosa richiede che tutte le associazioni vincolanti vengano eseguite staticamente. Ciò significa che le funzionalità che precedentemente richiedevano il binding dinamico devono essere eliminate o modificate. Nello specifico, l'istruzione with viene eliminata e la capacità della funzione eval di manomettere l'ambiente del chiamante è severamente 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 si dichiara esplicitamente una variabile, viene dichiarata implicitamente una variabile globale. Ciò semplifica la programmazione per i principianti perché possono trascurare alcune delle loro faccende di base. Ma rende la gestione di programmi più grandi molto più difficile e degrada in modo significativo l'affidabilità. Quindi, in modalità rigorosa, le variabili globali implicite non vengono più create. Dovresti dichiarare esplicitamente tutte le tue variabili.

Perdita globale

Ci sono un certo numero di situazioni che potrebbero far sì che this sia legato all'oggetto globale. Ad esempio, se si dimentica di fornire il new prefisso quando si chiama una funzione di costruzione, il costruttore si collegherà in modo imprevisto all'oggetto globale, quindi anziché inizializzare un nuovo oggetto, invece, manometterà silenziosamente le variabili globali. In queste situazioni, la modalità strict lo vincolerà a undefined , il che farà sì che il costruttore lanci un'eccezione, consentendo di rilevare molto prima l'errore.

Rumoroso Fallimento

JavaScript ha sempre avuto proprietà di sola lettura, ma non è stato possibile crearle da soli fino a quando la funzione Object.createProperty di ES5 non ha Object.createProperty tale capacità. Se si è tentato di assegnare un valore a una proprietà di sola lettura, si sarebbe verificato un errore. Il compito non cambierebbe il valore della proprietà, ma il tuo programma procederà come se lo fosse. Questo è un rischio di integrità che può far sì che i programmi entrino in uno stato incoerente. In modalità rigorosa, il tentativo di modificare una proprietà di sola lettura genera un'eccezione.

Octal

La rappresentazione ottale (o base 8) dei numeri era estremamente utile quando si eseguiva la programmazione a livello macchina su macchine le cui dimensioni di parola erano un multiplo di 3. Avevi bisogno di ottale quando lavoravi con il mainframe CDC 6600, che aveva una dimensione di parola di 60 bit. Se si potesse leggere ottale, si potrebbe guardare una parola come 20 cifre. Due cifre rappresentavano il codice operativo e una cifra identificava uno degli 8 registri. Durante la transizione lenta dai codici macchina ai linguaggi di alto livello, si è pensato fosse utile per fornire forme ottali nei linguaggi di programmazione.

In C, è stata selezionata una rappresentazione estremamente sfortunata dell'ottualità: lo zero iniziale. Quindi in C, 0100 significa 64, non 100, e 08 è un errore, non 8. Ancora più sfortunatamente, questo anacronismo è stato copiato in quasi tutte le lingue moderne, incluso JavaScript, dove è usato solo per creare errori. Non ha altro scopo. Quindi in modalità rigorosa, le forme ottali non sono più consentite.

Et cetera

Gli argomenti pseudo array diventano un po 'più simili ad array in ES5. In modalità rigorosa, perde le sue proprietà di caller e caller . Ciò rende possibile passare i tuoi arguments a un codice non fidato senza rinunciare a un sacco di contesto confidenziale. Inoltre, la proprietà arguments delle funzioni viene eliminata.

In modalità rigorosa, le chiavi duplicate in una funzione letterale generano 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ò delete sue variabili. Un tentativo di delete una proprietà non configurabile ora genera un'eccezione. I valori primitivi non sono implicitamente avvolti.

Parole riservate per versioni future 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 e yield

Ulteriori letture




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

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

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

La modalità rigorosa di ECMAScript 5 è un sottoinsieme limitato del linguaggio JavaScript, che elimina i deficit rilevanti del linguaggio e offre 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 l'opzione -statement in modalità rigorosa.
  • In modalità rigorosa tutte le variabili devono essere dichiarate: se si assegna un valore a un identificatore che non è stato dichiarato come variabile, funzione, parametro funzione, parametro catch-clause o proprietà Object globale, si otterrà un ReferenceError . In modalità normale l'identificatore è implicitamente dichiarato come variabile globale (come proprietà Object globale)
  • Nella modalità strict la parola chiave this ha il valore undefined in funzioni invocate come funzioni (non come metodi). (Nella modalità normale this punta sempre Object globale). 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 apply in modalità strict, allora this è esattamente il valore del primo argomento call() o apply() . (Nella modalità normale, null e undefined vengono sostituiti Object globale e i valori, che non sono oggetti, vengono convertiti in oggetti.)

  • Nella modalità strict otterrai un TypeError quando tenti di assegnare proprietà readonly o di definire nuove proprietà per un oggetto non estensibile. (In modalità normale entrambi falliscono senza messaggi di errore.)

  • In modalità rigorosa, quando si passa il codice a eval() , non è possibile dichiarare o definire variabili o funzioni nell'ambito del chiamante (poiché è 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 dopo che eval() termina l'esecuzione.
  • Nella modalità strict l'argomento-oggetto di una funzione contiene una copia statica dei valori, che vengono passati a quella funzione. In modalità normale l'argomento-oggetto ha un comportamento un po '"magico": gli elementi dell'array e i parametri di funzione nominati fanno riferimento allo stesso valore.
  • Nella modalità strict otterrai un SyntaxError quando l'operatore di delete è seguito da un identificatore non qualificato (una variabile, una funzione o un parametro di funzione). In modalità normale l'espressione delete non farebbe nulla e verrà valutata come false .
  • Nella modalità strict otterrai un TypeError quando tenti di eliminare una proprietà non configurabile. (In modalità normale il tentativo fallisce semplicemente e l'espressione delete viene valutata su false ).
  • In modalità rigorosa viene considerato un errore sintattico quando si tenta di definire diverse proprietà con lo stesso nome per un oggetto letterale. (In modalità normale non ci sono errori.)
  • In modalità strict è considerato un errore sintattico quando una dichiarazione di funzione ha più parametri con lo stesso nome. (In modalità normale non ci sono errori.)
  • Nella modalità strict non sono consentiti i letterali ottali (questi sono letterali che iniziano con 0x . (In modalità normale alcune implementazioni consentono letterali ottali).
  • In modalità rigorosa, gli identificatori eval e gli arguments sono trattati come parole chiave. Non è possibile modificare il loro valore, non è possibile assegnargli un valore e non è possibile utilizzarli come nomi per variabili, funzioni, parametri di funzione o identificatori di un blocco di cattura.
  • In modalità rigorosa ci sono più restrizioni sulle possibilità di esaminare lo stack delle chiamate. arguments.caller e arguments.callee causano un TypeError in una funzione in modalità rigorosa. Inoltre, alcune proprietà caller e arguments delle funzioni in modalità strict causano TypeError quando si tenta di leggerle.



Se utilizzi un browser rilasciato nell'ultimo anno, probabilmente supporta la modalità Strict di JavaScript. Solo i browser più vecchi prima che ECMAScript 5 diventasse lo standard attuale non lo supportano.

Le virgolette attorno al comando assicurano che il codice funzioni ancora anche nei browser più vecchi (anche se le cose che generano un errore di sintassi in modalità rigorosa generalmente causano il malfunzionamento dello script in alcuni modi difficili da rilevare in quei vecchi browser).




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

  • Aprendo la strada alle future versioni di ECMAScript , utilizzando una delle nuove parole chiave riservate (in previsione per ECMAScript 6 ): implements , interface , let , package , private , protected , public , static e yield .

  • Dichiarare la funzione in blocchi

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

    var n = 023;
    
  • this punto per l'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 ).

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

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

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

  • Usando eval o arguments come nome argomento variabile o funzione

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

fonti:




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




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

Ovviamente si parla anche di quante sono (e di quelle) sono state misfeatures e di come ECMAScript 5 le risolva.




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

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 di direttiva che contiene una direttiva sull'uso rigoroso (vedere 14.1.1).
  • Il codice del modulo è sempre un codice di modalità rigoroso.
  • Tutte le parti di ClassDeclaration o ClassExpression sono codice di modalità rigoroso.
  • Il codice Eval è un codice di modalità rigoroso se inizia con un Prologo di direttiva che contiene una Direttiva sull'uso rigoroso o se la chiamata a eval è una valutazione diretta (vedere 12.3.4.1) contenuta nel codice di modalità rigoroso.
  • Il codice funzione è un codice di modalità rigoroso se la relativa FunctionDeclaration, FunctionExpression, GeneratorDeclaration, GeneratorExpression, MethodDefinition o ArrowFunction è contenuta nel codice della modalità strict o se il codice che produce il valore dello slot interno [[ECMAScriptCode]] della funzione inizia con un prologo di direttiva che contiene una direttiva sull'uso rigoroso.
  • Il codice funzione fornito come argomento per i costruttori di funzione e generatore incorporati è il codice della modalità rigorosa se l'ultimo argomento è una stringa che, quando elaborata, è un FunctionBody che inizia con un prologo direttiva che contiene una direttiva sull'uso rigoroso.



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

  1. Impedisce la dichiarazione accidentale di variabili globali . L'utilizzo "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 viene 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. Limiterà gli usi delle parole chiave come variabili. Cercando di usarli genererà errori.

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

Per saperne di più, puoi fare riferimento qui .




"usare rigorosamente"; è lo sforzo dell'ECMA per rendere JavaScript un po 'più robusto. Porta in JS un tentativo di renderlo almeno un po '"severo" (gli altri linguaggi implementano regole severe fin 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 dattiloscritte, metodi tipizzati, ecc. Raccomando caldamente agli sviluppatori JavaScript di imparare un linguaggio più solido come Java o ActionScript3 e implementare le stesse migliori pratiche nel codice JavaScript, funzionerà meglio e sarà più facile debug.




Normalmente lo script java non segue regole rigide e quindi aumenta le possibilità di errori. Dopo l'uso "use strict", il codice dello script java dovrebbe seguire un rigido insieme di regole come in altri linguaggi di programmazione, come l'uso di terminatori, dichiarazioni prima dell'inizializzazione, ecc.

Se "use strict"viene utilizzato, il codice dovrebbe essere scritto seguendo un rigido insieme di regole, riducendo quindi le possibilità di errori e ambiguità.






Related