che cos'è la "modalità rigorosa" e come viene utilizzata?


134

Ho cercato il riferimento JavaScript sulla rete di sviluppatori Mozilla e mi sono imbattuto in qualcosa chiamato "strict mode". L'ho letto e ho difficoltà a capire cosa fa. Qualcuno può spiegare brevemente (in generale) qual è il suo scopo e come è utile?


Risposte:


149

Il suo scopo principale è fare più controlli.

Basta aggiungere "use strict";nella parte superiore del codice, prima di ogni altra cosa.

Ad esempio, blah = 33;è JavaScript valido. Significa che crei una variabile completamente globale blah.

Ma in modalità rigorosa è un errore perché non hai usato la parola chiave "var" per dichiarare la variabile.

La maggior parte delle volte non intendi creare variabili globali nel mezzo di un ambito arbitrario, quindi la maggior parte delle volte che blah = 33è scritto è un errore e il programmatore non voleva che fosse una variabile globale, intendevano per scrivere var blah = 33.

Allo stesso modo non consente molte cose che sono tecnicamente valide da fare. NaN = "lol"non produce un errore. Inoltre, non cambia il valore di NaN. l'uso rigoroso di questo (e simili strane dichiarazioni) produce errori. La maggior parte delle persone lo apprezza perché non c'è motivo di scrivere NaN = "lol", quindi molto probabilmente c'era un refuso.

Maggiori informazioni alla pagina MDN in modalità rigorosa


4
questo è un duplicato esatto della documentazione su MDN
nkcmr,

23
Cosa non capisci della sua utilità allora? Ha lo scopo di aiutare lo sviluppo catturando cose che sono errori validi ma molto probabili.
Simon Sarris,

34

Un aspetto della modalità rigorosa non già menzionato nella risposta di Simon è che la modalità rigorosa si imposta thissu undefinedfunzioni invocate tramite la chiamata di funzione.

Quindi cose del genere

function Obj() {
   this.a = 12;
   this.b = "a";
   this.privilegedMethod = function () {
      this.a++;
      privateMethod();
   };

   function privateMethod() {
     this.b = "foo";
   }
}

causerà un errore quando privateMethodviene chiamato (poiché non è possibile aggiungere una proprietà undefined), anziché aggiungere inutilmente una bproprietà all'oggetto globale.


4
sì, è necessario aggiungere privateMethod.bind(this)();e chiamare connew jsbin.com
hlcs,

Le restrizioni più importanti in modalità rigorosa: docs.microsoft.com/en-us/scripting/javascript/advanced/…
Krishna Mohan,

21

È stata aggiunta una modalità rigorosa in modo che ci fosse un sottoinsieme facilmente analizzabile staticamente di EcmaScript che sarebbe un buon obiettivo per le versioni future del linguaggio. La modalità rigorosa è stata progettata anche nella speranza che gli sviluppatori che si limitano alla modalità rigorosa commettano meno errori e che i bug che commettono si manifestino in modi più ovvi.

Harmony , che si spera diventerà la prossima versione principale di EcmaScript, sarà costruita sulla base di ES5 rigoroso.

Harmony si basa sulla modalità rigorosa ES5 per evitare troppe modalità.

Alcuni altri esperimenti linguistici dipendono anche dalla modalità rigorosa. SES dipende dall'analizzabilità della modalità rigorosa ES5.

Esperimento di progettazione SES (Secure ECMAScript)

Progettare un linguaggio di programmazione della capacità degli oggetti rimuovendo o riparando le funzionalità in ES5 / Strict.

Dovrebbe esserci una traduzione diretta da SES a ES5 / Strict.

L'allegato C della norma spiega le differenze tra la modalità rigorosa e la modalità normale.

La rigorosa restrizione di modalità ed eccezioni

  • Gli identificatori "implementa", "interfaccia", "let", "pacchetto", "privato", "protetto", "pubblico", "statico" e "rendimento" sono classificati come token FutureReservedWord in un codice di modalità rigoroso. (7.6.12 [?]).
  • Un'implementazione conforme, durante l'elaborazione del codice in modalità rigorosa, non può estendere la sintassi di NumericLiteral (7.8.3) per includere OctalIntegerLiteral come descritto in B.1.1.
  • Un'implementazione conforme, durante l'elaborazione del codice in modalità rigorosa (vedere 10.1.1), non può estendere la sintassi di EscapeSequence per includere OctalEscapeSequence come descritto in B.1.2.
  • L'assegnazione a un identificatore non dichiarato o un riferimento altrimenti irrisolvibile non crea una proprietà nell'oggetto globale. Quando si verifica un'assegnazione semplice all'interno di un codice in modalità rigorosa, il relativo LeftHandSide non deve essere considerato un riferimento irrisolvibile. In questo caso viene generata un'eccezione ReferenceError (8.7.2). Anche LeftHandSide potrebbe non essere un riferimento a una proprietà di dati con il valore dell'attributo {[[Writable]]: false}, a una proprietà accessor con il valore dell'attributo {[[Set]]: undefined}, né a un inesistente proprietà di un oggetto la cui proprietà interna [[Estensibile]] ha il valore falso. In questi casi viene generata un'eccezione TypeError (11.13.1).
  • L'eval identificatore o gli argomenti potrebbero non apparire come LeftHandSideExpression di un operatore di assegnazione (11.13) o di PostfixExpression (11.3) o come UnaryExpression operati da un prefisso Increment (11.4.4) o un prefisso Decrement (11.4.5) . Gli oggetti Argomenti per le funzioni in modalità rigorosa definiscono proprietà accessor non configurabili denominate "caller" e "callee" che generano un'eccezione TypeError all'accesso (10.6).
  • Gli oggetti Argomenti per le funzioni in modalità rigorosa non condividono in modo dinamico i valori delle proprietà indicizzate dell'array con i corrispondenti bind dei parametri formali delle loro funzioni. (10.6). Per le funzioni in modalità rigorosa, se viene creato un oggetto argomenti, l'associazione degli argomenti identificatore locale all'oggetto argomenti è immutabile e quindi potrebbe non essere la destinazione di un'espressione di assegnazione. (10.5).
  • È un SyntaxError se il codice in modalità rigorosa contiene un ObjectLiteral con più di una definizione di qualsiasi proprietà dei dati (11.1.5). È un SyntaxError se l'identificatore "eval" o l'identificatore "argomenti" si verifica come identificatore in un PropertySetParameterList di un PropertyAssignment che è contenuto in un codice rigoroso o se il suo FunctionBody è un codice rigoroso (11.1.5).
  • Il codice eval in modalità rigorosa non può istanziare variabili o funzioni nell'ambiente variabile del chiamante per valutare. Invece, viene creato un nuovo ambiente variabile e quell'ambiente viene utilizzato per l'istanza di associazione delle dichiarazioni per il codice eval (10.4.2).
  • Se questo viene valutato con un codice di modalità rigoroso, questo valore non viene forzato su un oggetto. A questo valore di null o indefinito non viene convertito nell'oggetto globale e i valori primitivi non vengono convertiti in oggetti wrapper. Questo valore trasmesso tramite una chiamata di funzione (incluse le chiamate effettuate utilizzando Function.prototype.apply e Function.prototype.call) non obbliga il valore passato a un oggetto (10.4.3, 11.1.1, 15.3.4.3, 15.3. 4.4).
  • Quando si verifica un operatore di eliminazione all'interno di un codice in modalità rigorosa, viene generato un SyntaxError se la sua UnaryExpression è un riferimento diretto a una variabile, argomento di funzione o nome di funzione (11.4.1).
  • Quando si verifica un operatore di eliminazione nel codice di modalità rigorosa, viene generato un errore di tipo se la proprietà da eliminare ha l'attributo {[[Configurabile]]: false} (11.4.1). È un SyntaxError se VariableDeclaration o VariableDeclarationNoIn si verifica all'interno di un codice rigoroso e il suo identificatore è eval o argomenti (12.2.1).
  • Il codice della modalità rigorosa potrebbe non includere un WithStatement. Il verificarsi di un WithStatement in tale contesto è un SyntaxError (12.10).
  • È un SyntaxError se un TryStatement con un Catch si verifica all'interno di un codice rigoroso e l'identificatore della produzione Catch è eval o argomenti (12.14.1)
  • È un SyntaxError se l'identificativo eval o gli argomenti compaiono all'interno di un FormalParameterList di una modalità rigorosa FunctionDeclaration o FunctionExpression (13.1)
  • Una funzione di modalità rigorosa potrebbe non avere due o più parametri formali con lo stesso nome. Un tentativo di creare una tale funzione utilizzando un costruttore FunctionDeclaration, FunctionExpression o Function è SyntaxError (13.1, 15.3.2).
  • Un'implementazione non può estendere, oltre a quanto definito in questa specifica, significati all'interno di funzioni in modalità rigorosa di proprietà denominate chiamante o argomenti di istanze di funzioni. Il codice ECMAScript non può creare o modificare proprietà con questi nomi su oggetti funzione che corrispondono a funzioni in modalità rigorosa (10.6, 13.2, 15.3.4.5.3).
  • È un SyntaxError utilizzare all'interno del codice di modalità rigorosa gli identificatori eval o gli argomenti come identificatore di una FunctionDeclaration o FunctionExpression o come nome di parametro formale (13.1). Il tentativo di definire dinamicamente una funzione di modalità così rigorosa utilizzando il costruttore Function (15.3.2) genererà un'eccezione SyntaxError.

6

ECMAScript 5 ha introdotto il concetto di modalità rigorosa .

Richiamo della modalità rigorosa nel codice

La modalità rigorosa si applica a interi script o a singole funzioni. Non si applica alle istruzioni di blocco racchiuse tra parentesi graffe, il tentativo di applicarlo a tali contesti non fa nulla.

Script intero:

Supponiamo che stiamo creando app.js, quindi l'aggiunta della prima istruzione use script imporrà una modalità rigorosa per l'intero codice.

// app.js whole script in strict mode syntax
use strict”;
// Now you can start writing your code 

Modalità rigorosa per la funzione:

Per invocare la modalità rigorosa per una funzione, inserisci la frase esatta "usa rigoroso"; all'inizio del corpo della funzione prima di qualsiasi altra istruzione.

function yourFunc(){
 "use strict";

 // Your function code logic
}

La modalità Strict incorpora diverse modifiche alla normale semantica Javascript. La prima modalità rigorosa elimina alcuni errori silenziosi JavaScript modificandoli per generare errori.

Ad esempio: codice usando la modalità rigorosa

inserisci qui la descrizione dell'immagine

Nell'esempio di codice precedente senza utilizzare la modalità rigorosa nel codice Non genererà un errore. Poiché stiamo accedendo alla variabile xsenza dichiararla. Quindi, in modalità rigorosa, l'accesso alla variabile non dichiarata genera un errore.

Ora proviamo ad accedere alla variabile x senza dichiararla senza modalità rigorosa.

(function(){
    x = 3;
})();

// Will not throw an error

Vantaggio dell'uso della modalità rigorosa:

  • Elimina gli errori silenziosi di JavaScript lanciando l'errore.
  • Correzione di errori che impediscono al motore JavaScript di eseguire l'ottimizzazione.
  • Rendi il codice più veloce a volte rispetto al codice identico che non è in modalità rigorosa
  • Vieta alcune sintassi che potrebbero essere definite nella versione futura di ECMAScript.

5

La modalità rigorosa apporta numerose modifiche alla normale semantica JavaScript.

  • la modalità rigorosa elimina alcuni errori silenziosi JavaScript modificandoli per generare errori.

  • la modalità rigorosa corregge gli errori che rendono difficile per i motori JavaScript eseguire le ottimizzazioni.

  • la modalità rigorosa vieta alcune sintassi che potrebbero essere definite nelle versioni future di ECMAScript.


1

ECMAScript5introduce alcuni nuovi oggetti e proprietà e anche il cosiddetto "strict mode".

La modalità rigorosa è un sottoinsieme della lingua che esclude le funzionalità obsolete. La modalità rigorosa è opt-in e non obbligatoria, il che significa che se si desidera che il codice venga eseguito in modalità rigorosa, si dichiara l'intenzione utilizzando (una volta per funzione o una volta per l'intero programma) la seguente stringa:

"use strict";

1

2017 e finalmente ho trovato la documentazione:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

La modalità rigorosa è un modo per optare per una variante limitata di JavaScript. La modalità Strict non è solo un sottoinsieme: ha intenzionalmente una semantica diversa dal codice normale. I browser che non supportano la modalità rigorosa eseguiranno il codice della modalità rigorosa con un comportamento diverso rispetto ai browser che lo fanno, quindi non fare affidamento sulla modalità rigorosa senza test delle funzionalità per il supporto degli aspetti rilevanti della modalità rigorosa. Codice di modalità rigoroso e codice di modalità non rigoroso possono coesistere, pertanto gli script possono attivare la modalità rigorosa in modo incrementale.


La modalità rigorosa apporta numerose modifiche alla normale semantica JavaScript. Innanzitutto, la modalità rigorosa elimina alcuni errori silenziosi JavaScript modificandoli per generare errori. In secondo luogo, la modalità rigorosa corregge gli errori che rendono difficile per i motori JavaScript eseguire le ottimizzazioni: a volte può essere eseguito un codice in modalità rigorosa per l'esecuzione più veloce di un codice identico che non è una modalità rigorosa. In terzo luogo, la modalità rigorosa vieta alcune sintassi che potrebbero essere definite nelle versioni future di ECMAScript.


0

Domanda: Di
seguito è riportato il problema che ho riscontrato, seguivo un'esercitazione e alla fine ho cercato di compilare il seguente scssfile e di provare a generare codice CSS da esso,

.fatty{
  width: percentage(6/7);
}

utilizzando la seguente gulpfile.jsattività:

var gulp = require('gulp');
var sass = require('gulp-sass');

gulp.task('sass', function () {
    return gulp.src('app/scss/styles.scss')
        .pipe(sass())
        .pipe(gulp.dest('app/css'))
});

Quindi l'errore che sto ricevendo è il seguente:

~/htdocs/Learning/gulp1/node_modules/gulp-sass/index.js:66
    let sassMap;
    ^^^

SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:373:25)
// stacktrace here...

Soluzione:
Quindi mi mostra il index.jsfile che si trova all'interno del mio modulo gulp-sass (che è sostanzialmente bloccato e non dovrebbe essere modificato). Ma se vado con forza e aggiungo la "use_strict"parte superiore di quel index.jsfile, esegue il mio compito senza problemi.

Ero impotente, quindi continuo a usarlo come soluzione! Ma poi, dopo aver esaminato alcune altre domande e risposte, ho visto la seguente risposta come segue:

sudo npm install -g n
sudo n stable

e prima ho aggiornato i miei NodeJs (a Version10.x), e poi ho ricostruito Gulp eseguendo i seguenti comandi come indicato dal Terminale:

npm rebuild node-sass --force

E va tutto bene. Ecco come è stato risolto. Ho annullato le modifiche che ho fatto per il index.jsfile del modulo gulp. E ora funziona senza problemi.

Spero che questa risposta sia utile a qualcuno là fuori!

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.