Table of Contents
Il JavaScript rimane uno dei linguaggi di programmazione più utilizzati sul web, alimentando tutto da forme interattive semplici a applicazioni complesse di singola pagina. Poiché i progetti crescono in dimensioni e membri del team aumentano, la necessità di codice affidabile e prevedibile diventa fondamentale.
Che cosa è la modalità Strict?
Quando abilitato, il motore JavaScript esegue il codice in un insieme di vincoli che eliminano alcune delle caratteristiche più incisive della lingua. L'idea dietro modalità rigorose è quella di fornire agli sviluppatori un feedback precedente su potenziali problemi. Ad esempio, in modalità non-strict (spesso chiamato "modalità numerica"), assegnando un valore a una modalità globale non dichiarata crea in modo silenzioso una variabile stretta.
ECMAScript 5 ha introdotto modalità rigorose nel 2009 come modo per evolvere il linguaggio senza rompere la compatibilità all'indietro. Gli sviluppatori potrebbero optare nel nuovo, comportamento più rigoroso aggiungendo semplicemente in cima a uno script o una funzione. Da allora, la modalità rigorosa è diventata una pratica consigliata in molte guide di stile e viene applicata automaticamente nei moderni costrutti JavaScript come moduli ES (import/export) e corpi di classe.
Come Attivare la Modalità Strict
Abilitare la modalità rigorosa è semplice: si inserisce la stringa letterale [] (o ) all'inizio di uno script o funzione. Questa direttiva non è una dichiarazione ma un pragma che dice al motore di analizzare il codice successivo in modalità rigorosa. Può essere applicato a due ambiti: globalmente (per un intero script) o localmente (per una singola funzione).
Modalità di Script-Level Strict
Per abilitare la modalità rigorosa per un intero file JavaScript o inline [ blocco, posizionare come la prima riga dello script (prima di qualsiasi altra dichiarazione).
// script.js
'use strict';
var x = 10;
console.log(x); // works normally
// Attempting to use undeclared variables throws an error
y = 20; // ReferenceError: y is not defined
Se si concatenano più script, solo quelli che iniziano con ] saranno eseguiti in modalità rigorosa. È importante notare che uno script di modalità rigorosa non può mescolarsi con il codice non-stretto nello stesso file a meno che non si utilizzi lo scoping a livello di funzione.
Modalità di funzionamento-scivolo
È inoltre possibile attivare modalità rigorose all'interno di una funzione specifica, lasciando il resto dello script in modalità sloppy. Questo è utile quando gradualmente migrando un codebase o quando si desidera controllare rigorosamente solo per determinate funzioni.
function strictFunction() {
'use strict';
// Inside this function, strict mode applies
var a = 1;
b = 2; // ReferenceError: b is not defined
}
function sloppyFunction() {
// Outside strictFunction, sloppy mode still applies
c = 3; // creates global variable c
}
La modalità rigorosa a livello di funzione si applica solo al codice della funzione, non a qualsiasi funzione nidificata (a meno che non dichiarino anche ). Tuttavia, in pratica, è comune impostare modalità rigorose a livello di file per coerenza.
Moduli e classi
Con l'avvento di ES6 (ES2015), JavaScript ha introdotto moduli e classi. Entrambi sono automaticamente in modalità rigorosa per impostazione predefinita. Pertanto, se si scrive il codice utilizzando /] sintassi o definire un , non è necessario aggiungere ] – la modalità di restrizione viene applicata automaticamente.
// module.js (no 'use strict' needed)
export function add(a, b) {
// strict mode is active here
return a + b;
}
// class definition (strict mode active)
class MyClass {
constructor(value) {
this.value = value;
}
}
Questa applicazione automatica rende il codice in moduli e classi intrinsecamente più sicuro e più facile da ragionare.
Vantaggi chiave di utilizzo della modalità rigorosa
La modalità Strict offre una serie di vantaggi che migliorano direttamente la qualità del codice, la sicurezza e l'esperienza dello sviluppatore.
Previene le variabili globali accidentali
In modalità non-strict, assegnare un valore a una variabile non dichiarata crea automaticamente una proprietà sull'oggetto globale ([[] nei browser, in Node.js). Questo può facilmente accadere a causa di errori tipografici o dichiarazioni dimenticate, inquinando lo spazio dei nomi globale e causando bug sottili.
// Non-strict: silently creates global variable
function setup() {
developer = "Alice"; // accidentally global
}
// Strict: throws ReferenceError
function setup() {
'use strict';
developer = "Alice"; // ReferenceError: developer is not defined
}
Questo esecutore costringe gli sviluppatori a dichiarare esplicitamente variabili con [, , o , riducendo bug correlati all'ambito.
Elimina errori silenziosi
JavaScript è spesso perdonare quando le operazioni non riescono silenziosamente. Ad esempio, assegnando a una proprietà di sola lettura (come o un oggetto congelato) semplicemente non fa nulla in modalità sloppy. In modalità rigorosa, tali incarichi gettano un . Allo stesso modo, tenta di eliminare le proprietà indelebili (ad esempio, )]) gettare un feedback molto più facile di ritorno [
// Non-strict: assignment silently fails
var obj = Object.freeze({name: "Bob"});
obj.name = "Charlie"; // silently ignored
// Strict: TypeError thrown
'use strict';
var obj = Object.freeze({name: "Bob"});
obj.name = "Charlie"; // TypeError: Cannot assign to read-only property 'name'
Previene nomi di parametro duplicati
In modalità non-strict, le funzioni possono avere nomi di parametri duplicati, che possono portare a comportamenti confusi (l'ultimo duplicato sovrascrive quelli precedenti).
// Non-strict: allowed
function sum(a, a, c) {
return a + a + c; // a equals the second argument passed
}
// Strict: SyntaxError
'use strict';
function sum(a, a, c) { // SyntaxError: Duplicate parameter name not allowed in strict mode
return a + a + c;
}
Questa restrizione aiuta a prevenire la sovrascrittura accidentale di parametri, rendendo le firme di funzione più chiare e meno incline agli errori.
Limita la dichiarazione
La dichiarazione è stata a lungo considerata dannosa perché crea ambiguità sulla risoluzione variabile e degrada le prestazioni. La modalità rigorosa permette completamente l'affermazione [[], gettando un ]] al momento della compilazione. Questa rimozione incoraggia gli sviluppatori a utilizzare modelli più prevedibili, come la distruzione o l'accesso esplicito di proprietà.
più sicuro
In modalità non-strict, può introdurre nuove variabili nell'ambito circostante, portando ad effetti collaterali imprevedibili. La modalità rigorosa cambia il comportamento di in modo che crei variabili solo all'interno del codice evale stesso – non trapelano nel contesto di inclosing, rendendo il codice più facile da ragionare e impedisce l'inquinamento accidentale di portata.
// Non-strict: eval creates variable in outer scope
var x = 1;
eval("var x = 2;");
console.log(x); // 2
// Strict: eval has its own scope
'use strict';
var x = 1;
eval("var x = 2;");
console.log(x); // 1
Proibizioni Letterari Numerici Ottali
Storicamente, JavaScript ha interpretato i numeri con uno zero di primo piano (ad esempio, ) come ottale (base 8). Questo comportamento spesso ha causato confusione e bug, soprattutto quando si tratta di stringhe come "010" che vengono analizzate come numeri.
// Non-strict: 010 means octal 8
console.log(010); // 8
// Strict: SyntaxError
'use strict';
console.log(010); // SyntaxError: Octal literals are not allowed in strict mode
Disabilita Deleting Plain Variables
In modalità non-strict, è possibile tentare di eliminare variabili o dichiarazioni di funzione, ma l'operazione fallisce silenziosamente ([[[] restituisce ]). La modalità rigorosa lancia un se si tenta di eliminare una variabile normale, funzione o parametro funzione.
// Non-strict: attempt silently fails
var a = 1;
delete a; // false; a still exists
// Strict: SyntaxError
'use strict';
var a = 1;
delete a; // SyntaxError: Delete of an unqualified identifier in strict mode
Miglioramenti di sicurezza e prestazioni aggiuntivi
Oltre alle restrizioni specifiche, la modalità rigorosa consente ai motori JavaScript di eseguire alcune ottimizzazioni altrimenti impossibili. Poiché la modalità rigorosa elimina alcuni comportamenti dinamici (come l'affermazione [ e i globali impliciti), il motore può meglio prevedere come le variabili saranno utilizzate, portando ad una più rapida esecuzione in alcuni casi. Inoltre, la modalità rigorosa disabilita la proprietà ] e la proprietà ] dei rischi di stack che erano
Esempi pratici di modalità rigorosa in azione
Per consolidare la comprensione, camminiamo attraverso una serie di esempi che contrastano la modalità sloppy con modalità rigorose, che dimostrano le modalità di feedback rigorose immediate.
Esempio 1: Assegnazione Variabile Non dichiarata
// sloppy.js
function userInfo() {
name = "John"; // silently creates global 'name'
}
userInfo();
console.log(window.name); // "John" (in browsers)
// strict.js
'use strict';
function userInfo() {
name = "John"; // ReferenceError: name is not defined
}
userInfo();
Senza modalità rigorose, un semplice tipo come ] invece di può inquinare l'ambito globale.
Esempio 2: Assegnazione a una proprietà globale
// sloppy mode
undefined = 5; // silently fails (undefined remains undefined)
NaN = 6; // silently fails
console.log(undefined, NaN); // undefined, NaN
// strict mode
'use strict';
undefined = 5; // TypeError: Cannot assign to read-only property 'undefined' of object '#<Window>'
NaN = 6; // TypeError
La modalità rigorosa impedisce la sovrascrittura accidentale di costanti globali che non dovrebbero mai cambiare, aiutando a preservare l'integrità dell'ambiente runtime.
Esempio 3: Duplicare Nome Proprietà Oggetto
In modalità rigoroso, i nomi di proprietà duplicati in literals di oggetti causano un . In modalità sloppy, l'ultimo vince. Ciò è particolarmente utile per rilevare errori durante la modifica di oggetti di configurazione o quando si copia il codice.
// sloppy: works, last value wins
var config = {
host: "example.com",
host: "backup.com" // no error
};
console.log(config.host); // "backup.com"
// strict: SyntaxError
'use strict';
var config = {
host: "example.com",
host: "backup.com" // SyntaxError: Duplicate data property in object literal not allowed in strict mode
};
Pitfalls comuni e migrazione alla modalità rigorosa
Mentre la modalità rigorosa porta molti vantaggi, la migrazione di un grande codebase esistente può presentare sfide. Alcuni modelli più vecchi che sono stati considerati accettabili in ES3/5 possono ora fallire.
- Assegnazioni variabili non dichiarate[: Il codice che si basa su globali impliciti deve essere aggiornato per dichiarare variabili.
- Utilizzando dichiarazioni[]: Questi devono essere rifatto in accessi espliciti di proprietà.
- Litterali ottali[]]: Sostituire [] con ] o decimale .
- Accesso []: Questo è insoddisfatto; usare invece le espressioni di funzione nominate.
- Nomi dei parametri duplicati[[]: devono essere rimossi o rinominati.
- Utilizzando su variabili o funzioni[: Questa operazione è vietata.
Il processo di migrazione è spesso incrementale. È possibile abilitare la modalità rigorosa funzione per funzione utilizzando il [ pragma funzioni interne, testare accuratamente, e poi abilitarlo a livello globale una volta che si è sicuri. Strumenti come ESLint con la sua regola può aiutare a identificare automaticamente le violazioni. Inoltre, utilizzando moduli ES o classi automaticamente ti dà un comportamento di modalità rigoroso, così migrating alla sintassi moderna è un percorso naturale verso il codice rigido.
Vale anche la pena notare che la modalità rigorosa non è un killer delle prestazioni, infatti, come accennato, alcuni motori possono ottimizzare meglio il codice di modalità rigoroso. Il controllo di runtime iniziale per la direttiva è trascurabile, e la chiarezza del codice generale e la sicurezza superano gran parte qualsiasi costo marginale.
Conclusione e migliori pratiche
La modalità rigorosa di JavaScript è uno strumento potente per scrivere codice più robusto, manutenbile e sicuro.Optando in questo sottoinsieme ristretto della lingua, gli sviluppatori acquisiscono la rilevazione precoce di errori comuni, evitano costrutti pericolosi e beneficiano di prestazioni migliori in molti casi.
Iniziare utilizzando un linter per identificare le violazioni, risolverle gradualmente e testare frequentemente. Gli strumenti e i framework JavaScript moderni spesso assumono modalità rigorose (o lo fanno rispettare), in modo da allineare con tale convenzione assicura compatibilità e coerenza.
Per immergersi più in profondità, fare riferimento alla documentazione MDN per una lista completa di restrizioni ed esempi. Per il contesto storico, la specifica ECMAScript] spiega le regole formali. Inoltre, il ELint regola rigorosa fornisce un modo di calcolo automatico per far rispettare l'affidabilità costante.