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



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 attualmente hai foo = "bar" senza prima definire foo , il tuo codice inizierà a non funzionare ... il che è una buona cosa secondo me.

Question

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?




When adding "use strict"; , the following cases will throw a SyntaxError before the script is executing:

  • Paving the way for future ECMAScript versions , using one of the newly reserved keywords (in prevision for ECMAScript 6 ): implements , interface , let , package , private , protected , public , static , and yield .

  • Declaring function in blocks

    if(a<b){ function f(){} }
    
  • Octal syntax

    var n = 023;
    
  • this point to the global object.

     function f() {
          "use strict";
          this.a = 1;
     };
     f(); 
    
  • Declaring twice the same name for a property name in an object literal

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

    This is no longer the case in ECMAScript 6 ( bug 1041128 ).

  • Declaring two function arguments with the same name function

    f(a, b, b){}
    
  • Setting a value to an undeclared variable

    function f(x){
       "use strict";
       var a = 12;
       b = a + x*35; // error!
    }
    f();
    
  • Using delete on a variable name delete myVariable;

  • Using eval or arguments as variable or function argument name

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

fonti:




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 corrente 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).




"use strict"; is the ECMA effort to make JavaScript a little bit more robust. It brings in JS an attempt to make it at least a little "strict" (other languages implement strict rules since the 90s). It actually "forces" JavaScript developers to follow some sort of coding best practices. Still, JavaScript is very fragile. There is no such thing as typed variables, typed methods, etc. I strongly recommend JavaScript developers to learn a more robust language such as Java or ActionScript3, and implement the same best practices in your JavaScript code, it will work better and be easier to debug.




Note that use strict was introduced in EcmaScript 5 and was kept since then.

Below are the conditions to trigger strict mode in ES6 and ES7 :

  • Global code is strict mode code if it begins with a Directive Prologue that contains a Use Strict Directive (see 14.1.1).
  • Module code is always strict mode code.
  • All parts of a ClassDeclaration or a ClassExpression are strict mode code.
  • Eval code is strict mode code if it begins with a Directive Prologue that contains a Use Strict Directive or if the call to eval is a direct eval (see 12.3.4.1) that is contained in strict mode code.
  • Function code is strict mode code if the associated FunctionDeclaration, FunctionExpression, GeneratorDeclaration, GeneratorExpression, MethodDefinition, or ArrowFunction is contained in strict mode code or if the code that produces the value of the function's [[ECMAScriptCode]] internal slot begins with a Directive Prologue that contains a Use Strict Directive.
  • Function code that is supplied as the arguments to the built-in Function and Generator constructors is strict mode code if the last argument is a String that when processed is a FunctionBody that begins with a Directive Prologue that contains a Use Strict Directive.



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



The main reasons why developers should use "use strict" are:

  1. Prevents accidental declaration of global variables.Using "use strict()" will make sure that variables are declared with var before use. 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: The "use strict" directive is only recognized at the beginning of a script or a function.
  3. The string "arguments" cannot be used as a variable:

    "use strict";
    var arguments = 3.14;    // This will cause an error
    
  4. Will restrict uses of keywords as variables. Trying to use them will throw errors.

In short will make your code less error prone and in turn will make you write good code.

To read more about it you can refer http://www.w3schools.com/js/js_strict.asp .




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 fase 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




There's a good talk by some people who were on the ECMAScript committee: Changes to JavaScript, Part 1: ECMAScript 5" about how incremental use of the "use strict" switch allows JavaScript implementers to clean up a lot of the dangerous features of JavaScript without suddenly breaking every website in the world.

Of course it also talks about just what a lot of those misfeatures are (were) and how ECMAScript 5 fixes them.




Normally java script does not follow strict rules hence increasing chances of errors. After using "use strict" , the java script code should follow strict set of rules as like in other programming languages such as use of terminators, declaration before initialization etc.

If "use strict" is used then the code should be written by following a strict set of rules hence decreasing the chances of errors and ambiguities.




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 modalità rigorosa e 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.



"Usa rigorosamente"; è un'assicurazione che il programmatore non utilizzerà le proprietà libere o errate di JavaScript. È una guida, proprio come un righello ti aiuterà a fare linee rette. "Usa Strict" ti aiuterà a fare "Codifica Diretta".

Coloro che preferiscono non usare i righelli per fare le loro linee dritte di solito finiscono in quelle pagine per chiedere agli altri di eseguire il debug del loro codice.

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

La pratica moderna di JavaScript dovrebbe sempre evocare il "Use Strict"; pragma. The only reason that the ECMA Group has made the "Strict" mode optional is to permit less experienced coders access to JavaScript and give then time to adapt to the new and safer coding practices.




Just wanted to add some more points.

The Reason to Use Strict Mode--->

  • Strict mode makes it easier to write "secure" JavaScript.

  • Strict mode changes previously accepted "bad syntax" into real
    errori.

  • As an example, in normal JavaScript, mistyping a variable name
    creates a new global variable.

  • In strict mode, this will throw an error, making it impossible to accidentally create a global variable.

  • In strict mode, any assignment to a non-writable property, a
    getter-only property, a non-existing property, a non-existing
    variable, or a non-existing object, will throw an error.

The things that will throw errors in Strict Mode Using a variable, without declaring it, is not allowed:

"use strict";
 x = 3.14;                // This will cause an error

Objects are variables too.

Using an object, without declaring it, is not allowed:

  "use strict";
  x = {p1:10, p2:20};      // This will cause an error

Deleting a variable (or object) is not allowed.

  "use strict";
   var x = 3.14;
   delete x;                // This will cause an error

For security reasons, eval() is not allowed to create variables in the scope from which it was called:

"use strict";
 eval ("var x = 2");
 alert (x);               // This will cause an error

In function calls like f(), the this value was the global object. In strict mode, it is now undefined.

"use strict" is only recognized at the beginning of a script.






Links