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


Recentemente, ho eseguito alcuni dei miei codici JavaScript tramite Crockford JSLint 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 al "use strict"; stringa o è per uso futuro?


6701
2017-08-26 16:10


origine


risposte:


Questo articolo sulla modalità Strict Javascript potrebbe interessarti: John Resig - ECMAScript 5 Modalità rigorosa, JSON e altro

Per citare alcune parti interessanti:

La modalità rigorosa è una nuova funzionalità di ECMAScript 5 che consente di posizionare un programma o una funzione in un contesto operativo "rigoroso". Questo contesto rigoroso impedisce che alcune azioni vengano prese e genera più eccezioni.

E:

La modalità rigorosa aiuta in un paio di modi:

  • Cattura alcuni comuni blooper in codice, generando eccezioni.
  • Previene, o genera errori, quando vengono intraprese azioni relativamente "non sicure" (come ottenere l'accesso all'oggetto globale).
  • Disattiva le funzionalità che sono confuse o mal concepite.

Si noti inoltre che è possibile applicare la "modalità rigorosa" all'intero file ... Oppure è possibile utilizzarlo solo per una funzione specifica (ancora citando l'articolo di John Resig) :

// Non-strict code...

(function(){
  "use strict";

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

// Non-strict code... 

Quale potrebbe essere utile se devi mescolare il vecchio e il nuovo codice ;-)

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

Attualmente, lo è supportato da tutti i principali browser   (barra IE 9 e inferiore) .


4392
2017-08-26 16:15



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

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


1101
2017-08-26 16:14



La dichiarazione "use strict"; indica al browser di utilizzare la modalità Strict, che è una serie di JavaScript ridotta e più sicura.

Elenco delle caratteristiche (non esaustivo)

  1. Non consente le variabili globali. (Catture mancano var dichiarazioni e refusi nei nomi delle variabili)

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

  3. Tentativi di eliminare proprietà non cancellabili verranno lanciati ( delete Object.prototype)

  4. Richiede che tutti i nomi di 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. Proibisce la sintassi ottale ( var x = 023; alcuni sviluppatori ritengono erroneamente che uno zero precedente non modifichi il numero.)

  7. Proibisce il with parola chiave

  8. eval in modalità rigorosa non introduce nuove variabili

  9. Proibisce l'eliminazione di nomi semplici ( delete x;)

  10. Proibisce l'associazione o l'assegnazione dei nomi eval e arguments in qualsiasi forma

  11. La modalità rigorosa non ha alias proprietà di arguments oggetto con i parametri formali. (cioè in function sum (a,b) { return arguments[0] + b;} Funziona perché arguments[0] è legato a a e così via. )

  12. arguments.callee non è supportato

[Rif: Modalità rigorosa , Mozilla Developer Network ]


518
2017-11-24 21:22



Se le persone sono preoccupate dell'uso 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.
*/

368
2017-07-15 23:25



Una parola di cautela, tutti voi programmatori in difficoltà: applicare "use strict" al codice esistente può essere pericoloso! Questa cosa non è un adesivo di buon gusto, faccia felice che puoi dare uno schiaffo al codice per renderlo 'migliore'. Con il "use strict" pragma, il browser improvvisamente LANCIA le eccezioni in posti casuali che non ha mai gettato prima solo perché in quel punto stai facendo qualcosa che default / loose JavaScript consente felicemente, ma rigida aborrisce JavaScript! Potresti avere violazioni di rigore che si nascondono nelle chiamate usate raramente nel tuo codice che generano solo un'eccezione quando alla fine vengono eseguite, ad esempio nell'ambiente di produzione utilizzato dai 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 compilazione JSHint strettamente configurata che ti darà la certezza che non c'è un angolo scuro del tuo modulo che esploderà orribilmente solo perché hai attivato la modalità Strict. Oppure, ciao, ecco un'altra opzione: non aggiungere "use strict" a uno qualsiasi dei tuoi codici legacy, è probabilmente più sicuro in questo modo, onestamente. SICURAMENTE NON  Inserisci "use strict" a tutti i moduli che non possiedi o gestisci, come i moduli di terze parti.

Penso che anche se sia un animale in gabbia mortale, "use strict" può essere roba buona, ma devi farlo bene. Il momento migliore per andare rigorosi è quando il tuo progetto è greenfield e stai partendo da zero. Configurazione JSHint/JSLint con tutti gli avvertimenti e le opzioni alzati tanto quanto la tua squadra può sopportare, ottenere un buon build / test / assert system du jour truccato come Grunt+Karma+Chaie solo POI inizi a contrassegnare tutti i tuoi nuovi moduli come "use strict". Preparati a curare molti errori e avvertimenti. Assicurati che tutti comprendano la gravità configurando la build su FAIL if JSHint/JSLintproduce eventuali violazioni.

Il mio progetto non è stato un progetto greenfield quando l'ho adottato "use strict". Di conseguenza, il mio IDE è pieno di segni rossi perché non ce l'ho "use strict" su metà dei miei moduli, e JSHint si lamenta per questo. È un promemoria per me su cosa dovrei rifare in futuro. Il mio obiettivo è quello di essere senza segno rosso a causa di tutti i miei dispersi "use strict" dichiarazioni, ma sono passati anni.


182
2018-03-03 07:37



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

Il Modalità rigorosa JavaScript  è una funzionalità in ECMAScript 5 . Puoi attivare la modalità rigorosa dichiarandola nella parte superiore del tuo script / funzione.

'use strict';

Quando un motore JavaScript lo vede 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 letterale ottale. La modalità non rigida interpreterà questo come un valore letterale numerico con valore 24 (nella 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';?

  • Nel mio nuovo  Applicazione JavaScript: Assolutamente!  La modalità rigorosa può essere utilizzata come informatore quando stai facendo qualcosa di stupido con il tuo codice.

  • Nel mio esistente  Codice JavaScript: 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. Ecco perché utilizzando 'use strict'; improvvisamente non migliora il tuo codice .


Come uso la modalità rigorosa?

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

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

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

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

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

    Tutto nel ambito lessicale  di funzione doSomething sarà interpretato in modalità rigorosa. La parola ambito lessicale  è importante qui. Vedere questa risposta  per una spiegazione migliore


Quali cose sono proibite in modalità rigorosa?

Ho trovato un bel articolo  descrive diverse cose che sono vietate in modalità rigorosa (notare che questa non è una lista esclusiva):

Scopo

Storicamente, JavaScript è stato confuso su come funzioni   sono ambiti. A volte sembrano essere sistemati in modo statico, ma alcuni   le caratteristiche li fanno comportarsi come se fossero a livello dinamico. Questo è   confondere, rendere i programmi difficili da leggere e capire.   L'incomprensione causa bug. È anche un problema per le prestazioni.   L'ambito statico consentirebbe il binding variabile per la compilazione   tempo, ma il requisito per l'ambito dinamico significa che l'associazione deve essere   differito al runtime, che viene fornito con una prestazione significativa   pena.

La modalità rigorosa richiede che tutte le associazioni vincolanti vengano eseguite staticamente.   Ciò significa che le funzionalità che in precedenza richiedevano il binding dinamico   deve essere eliminato o modificato. Nello specifico, l'affermazione with è   eliminati e la capacità della funzione eval di manomettere il   l'ambiente del suo chiamante è severamente limitato.

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

Variabili globali implicite

JavaScript ha implicato variabili globali. Se   non si dichiara esplicitamente una variabile, una variabile globale lo è   implicitamente dichiarato per te. Questo facilita la programmazione   i principianti perché possono trascurare alcune delle loro funzioni di base   faccende. Ma rende molto più la gestione di programmi più grandi   difficile e degrada in modo significativo l'affidabilità. Quindi in senso stretto   modalità, le variabili globali implicite non vengono più create. Dovresti   dichiara esplicitamente tutte le tue variabili.

Perdita globale

Ci sono un certo numero di situazioni che potrebbero causare this   essere legato all'oggetto globale. Ad esempio, se ti dimentichi di   fornire il new prefisso quando si chiama una funzione di costruzione, il   il costruttore di this sarà legato inaspettatamente all'oggetto globale, quindi   invece di inizializzare un nuovo oggetto, sarà invece silenziosamente   manomissione delle variabili globali. In queste situazioni, la modalità rigorosa lo farà   invece legano this a undefined, che farà sì che il costruttore a   lanciare invece un'eccezione, consentendo di rilevare molto l'errore   prima.

Rumoroso Fallimento

JavaScript ha sempre avuto proprietà di sola lettura, ma tu   non sono riuscito a crearli da soli fino all'ES5 Object.createProperty   la funzione ha esposto quella capacità. Se si è tentato di assegnare un valore   a una proprietà di sola lettura, fallirebbe silenziosamente. L'incarico lo farebbe   non modificare il valore della proprietà, ma il tuo programma procederebbe come   sebbene avesse. Questo è un rischio di integrità che può causare programmi   entrare in uno stato incoerente. In modalità rigorosa, tentando di cambiare a   la proprietà di sola lettura genererà un'eccezione.

Octal

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

In C, una rappresentazione estremamente sfortunata di ottalità era   selezionato: 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. Così dentro   modalità rigorosa, le forme ottali non sono più consentite.

Et cetera

Gli argomenti pseudo array diventano un po 'di più   array-like in ES5. In modalità rigorosa, perde la sua callee e caller   proprietà. Questo rende possibile passare il tuo arguments a non fidati   codice senza rinunciare a un sacco di contesto confidenziale. Anche il    arguments la proprietà delle funzioni è eliminata.

In modalità rigorosa, i tasti duplicati in una funzione letterale generano a   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 una delle sue   parametri. Una funzione non può delete le sue variabili. Un tentativo di    delete una proprietà non configurabile ora genera un'eccezione. Primitivo   i valori 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


131
2018-01-29 11:35



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 che fossero nel tuo codice.

Apparentemente, nella fase iniziale ci saranno errori che non abbiamo mai incontrato prima. Per ottenere il massimo beneficio, dobbiamo eseguire test appropriati dopo aver attivato la modalità rigorosa per assicurarci di aver catturato tutto. Sicuramente non ci limitiamo a buttare use strict nel nostro codice e assumiamo che non ci siano errori. Quindi, il churn è che è ora di iniziare a utilizzare questa caratteristica del linguaggio 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 il tuo script e scansionerà rapidamente eventuali problemi e errori evidenti nel tuo codice.


122
2017-07-05 19:38



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 a Documentazione MDN  per maggiori 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 vengano introdotte le versioni future degli standard ECMAScript 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.

Il use strictdirettiva indica che il seguente codice (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 a use strict direttiva. Il contenuto di una funzione è considerato un codice rigoroso quando la funzione stessa è definita in un codice rigoroso o quando la funzione contiene a use strict direttiva. Codice passato a eval() il metodo è considerato un codice rigoroso quando eval() è stato chiamato da un codice rigoroso o contiene il use strict direttiva 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 puoi usare il with-statamento 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à del globale Object, quindi otterrai un ReferenceError. In modalità normale l'identificatore è implicitamente dichiarato come variabile globale (come proprietà del globale Object)
  • In modalità rigorosa la parola chiave this ha il valore undefined in funzioni invocate come funzioni (non come metodi). (Nella modalità normale this punta 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 viene invocata una funzione con call() o apply in modalità rigorosa, quindi this è esattamente il valore del primo argomento del call()o apply() invocazione. (Nella modalità normale null e undefined sono sostituiti dal globale Object e valori, che non sono oggetti, sono espressi in oggetti.)

  • In modalità rigorosa otterrai a TypeError, quando si tenta 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. Questo ambito è distrutto dopo 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.
  • In modalità rigorosa otterrai a SyntaxError quando il delete l'operatore è seguito da un identificatore non qualificato (una variabile, una funzione o un parametro di funzione). In modalità normale il delete espressione non farebbe nulla e verrà valutata false.
  • In modalità rigorosa otterrai a TypeError quando si tenta di eliminare una proprietà non configurabile. (In modalità normale il tentativo fallisce semplicemente e il deleteespressione è valutata a 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.)
  • In modalità rigorosa i letterali ottali non sono consentiti (questi sono letterali che iniziano con 0x. (In modalità normale alcune implementazioni consentono letterali ottali.)
  • In modalità rigorosa gli identificatori eval e 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 causa a TypeError in una funzione in modalità rigorosa. Inoltre, alcune proprietà caller e arguments delle funzioni in modalità strict causano a TypeError quando provi a leggerli.

81
2018-05-15 06:58