ECMAScript, che è sostenuta dall’Ecma International come garanzia per l’adozione su tutta la linea, è lo standard di quello che la maggior parte delle persone conoscono come JavaScript.
A rigor di termini (ma non volendo essere pignoli), JavaScript ed ECMAScript non sono esattamente la stessa cosa.
JavaScript è un dialetto di ECMAScript, ma le differenze sono generalmente irrilevanti e sono principalmente causate da ragioni storiche di compatibilità con le versioni precedenti. ECMAScript 5, l’ultima versione disponibile (e al quale ci riferiamo come ES5), porta con sè una serie di caratteristiche interessanti. La maggior parte di questi sviluppi sono stati progettati per migliorare la disciplina della programmazione con questo linguaggio.
Questo post tratta della modalità Strict, una caratteristica che ci servirà per affrontare alcune delle parti più notevoli del linguaggio. In sostanza si tratta di un nuovo modo di eseguire JavaScript, che fa sì che il runtime funzioni con una semantica leggermente diversa.

Cos'è la modalità Strict?
La modalità Strict è un modo per forzare il motore di runtime a interpretare e ad eseguire JavaScript con un semantica diversa da quella che possiamo fare con il modo non rigoroso. Il codice eseguito in modalità rigorosa ha le seguenti caratteristiche:

  1. Sono escluse alcune funzioni sintattiche e semantiche: non possiamo fare certe cose che sono ammesse negli altri casi.
  2. Modifica la semantica di alcune funzionalità: lo stesso codice funziona in modo diverso in modalità rigorosa e in modalità nonrigorosa.
  3. Restituisce più errori in alcuni casi: in situazioni in cui si ignorerebbe in modo trasparente o si eseguirebbe direttamente nella modalità non-ristretta.
  4. Si applica alle unità specifiche del codice: non si può applicare la modalità rigorosa a tutti i file .js contemporaneamente (a meno che non si concatenino insieme, nel qual caso è considerata una singola unità, almeno dal punto di vista del runtime).

L’obiettivo principale della modalità Strict è l’introduzione di una qualche forma di disciplina imposta dal runtime, necessaria per lo sviluppo con JavaScript. Ho sempre pensato che JavaScript è troppo dinamico e in qualche modo gioca contro di noi; la modalità rigorosa è una riduzione di questo dinamismo.
Quando si segna un segmento di codice come “strict“, molte delle parti più aperte di JavaScript rimangono sotto i criteri imposti dal motore, piuttosto che richiedere disciplina al programmatore.
Riesci a individuare l’errore in questo frammento di codice? Se abbiamo attivato la modalità Strict, il runtime lo rileva a prima vista!

[code lang=”javascript”] function cercaProdotto(numero) {
var prodotto = 0,
len = numero.length;
for(var i = 0; i < len; ++i) {
prdotto = prodotto * numero[i];
}
return prodotto;
}
[/code]
Compatibilità tra i browser
La maggior parte dei browser attuali supporta già la modalità Strict nei suoi motori Javascript, come Internet Explorer, Chrome, Firefox, Safari e Opera. In Internet Explorer (IE), la modalità Strict è disponibile a partire dalla versione 10. è possibile scaricare l’ultima piattaforma preliminare IE10 dal sito Test Drive di IE.
Tutti gli esempi in questo articolo sono state testate con la piattaforma preliminare IE10 utilizzando la console per valutare JavaScript. Gli esempi scelti sono stati testati anche su Chrome 13 e Firefox 7 Beta.
Contesti della modalità Strict
L’esecuzione di un pezzo di codice JavaScript in modalità Strict, di per sé, è abbastanza semplice, ecco un esempio:
[code lang=”javascript”] "use strict";
alert("Guardami! Sono in modalità Strict!");
[/code]
La cosa migliore è che questo si applica perfettamente anche al ECMAScript 3. (ES3 è la versione precedente di ECMAScript.
Cos’è successo a ES4? è successo proprio come il dodo!)
Un motore JavaScript ES3 ignora semplicemente la linea e poi procede a eseguire il resto dello script. In effetti questo tipo di sintassi per compatibilità con ES3 è stato uno degli obiettivi della progettazione in ES5. Una parte sorprendentemente ricca dell’implementazione di ES5 si può eseguire direttamente su JavaScript SS3.
La modalità Strict, tuttavia, è un esempio di funzionalità di ES5 che, forse, non può essere implementata tale e quale in JavaScript ES3 senza supporto aggiuntivo nel runtime.
I seguenti esempi di codice JavaScript possono essere utilizzati in modalità rigorosa:
1. Codice globale
Si tratta fondamentalmente di un codice eseguibile che è incluso all’interno di un tag <script>. Ad esempio:
[code lang=”html”] <script>
"use strict";
// Qui va il codice globale in modalità rigorosa
</script>
[/code]
Se si usa HTML5 non c’è bisogno di aggiungere l’attributo “type” nel tag script.
2. Codice di valutazione ('eval')
Il codice di valutazione include il prefisso della direttiva della modalità Strict:
[code lang=”javascript”] eval("’use strict’; // codice in modalità rigorosa");
[/code]
Oppure viene richiamato dal codice in modalità Strict:
[code lang=”javascript”] "use strict";
eval("// codice in modalità rigorosa");
[/code]
3. Codice di funzione
Sono funzioni che hanno la direttiva della modalità Strict precedendo una porzione del codice (la direttiva può essere posizionata ovunque, non importa):
[code lang=”javascript”] function foo() {
"use strict";
// codice in modalità rigorosa
}
[/code]
Le funzioni dichiarate nel codice in modalità Strict ereditano questa condizione:
[code lang=”javascript”] function foo() {
"use strict";
var bar = function () {
// codice in modalità rigorosa
};
bar();
}
[/code]
Conviene sapere che quest’ultimo esempio è particolarmente importante quando si definiscono i callbacks per diversi gestori di eventi.
è importante notare inoltre che la restrizione non si estende alle chiamate sullo stack. Questo è un esempio:
[code lang=”javascript”] function foo() {
// non si esegue in modalità rigorosa, anche se
// la funzione foo viene chiamata da una funzione
// che usa la modalità "strict"
}
function bar() {
"use strict";
foo();
}
bar();
[/code]
Restrizioni della modalità Strict
Ebbene, quali sono le restrizioni e le semantiche alternative che si applicano esattamente in modalità Strict? Rivediamo alcune delle principali
1. Gli identificatori devono essere dichiarati prima dell'assegnazione dei valori
Questo aspetto rende la modalità Strict uno strumento di grande valore in sé, anche se non fa niente altro. Le assegnazioni a variabili non dichiarate non vengono aggiunte automaticamente come proprietà estesa dell’oggetto globale.
[code lang=”javascript”] "use strict";
// ReferenceError: variabile non definida modalità rigorosa
foo = 10;
[/code]
In queste condizioni, il frammento di codice dell’esempio della sezione (Cos’è la modalità Strict?), non riuscirà a eseguirsi e restituirà un “Errore di Riferimento” (ReferenceError) perché il nome della variabile prodottocode> non è scritta bene nell’istruzione di assegnazione che compare all’interno del ciclo for.
[code lang=”javascript”] function cercaProdotto(numero) {
var prodotto = 0,
len = numero.length;
for(var i = 0; i < len; ++i) {
// ReferenceError: variabile non definida
// in modalità rigorosa
prdotto = prodotto * numero[i];
}
return prodotto;
}
print(cercaProdotto([1, 2, 3, 4, 5]));
[/code]
2. Non si aggiunge un contesto automatico per le chiamate a funzioni senza contesto
Le chiamate a funzioni, senza stabilire un contesto esplicito non utilizza automaticamente l’oggetto globale per il riferimento a this. Per esempio, consideriamo il seguente codice:
[code lang=”javascript”] function foo() {
// ritorna "true"
print(this === window);
}
foo();
[/code]
In questo caso, si chiama la funzione foo senza fissare un oggetto di contesto esplicito, vale a dire, non facciamo la chiamata utilizzando un’espressione come questa:
[code lang=”javascript”] foo.call({foo: "bar"});
[/code]
In modalità non rigorosa, la chiamata originale inizializza il contesto automaticamente come oggetto global, che nei browser è l’ggetto window. Dal momento che il codice di sopra è stato eseguito in modalità non rigorosa, l’espressione this === window restituisce true. Se cambiamo la funzione, come proposto nel seguente esempio, vediamo che this non è equivalente a window:
[code lang=”javascript”] function foo() {
"use strict";
// ritorna "false"
print(this === window);
}
foo();
[/code]
3. Le parole riservate non possono essere utilizzate come identificatori
Denominare variabili e funzioni, come eval, arguments, implements, let, private, public, yield, interface, package, protected o static, restituiscojno errori.
[code lang=”javascript”] "use strict";
var yield; // SyntaxError: atteso un identificatore
[/code]
4. Il mancato rispetto nella configurazione delle proprietà del SS5 genera errore
Quando si viola la configurazione di un descrittore di proprietà in SS5, come indicato nella linea guida, viene visualizzato un errore in modalità rigorosa, ma non nella modalità non rigorosa che semplicemente ignora questo fatto. Ecco alcuni esempi:

1. Scrivere valori in una proprietà non modificabile:
[code lang=”javascript”] "use strict";
var persona = Object.create({}, {
nome: {
value: "foo",
writable: false,
configurable: true,
enumerable: true
}
});
// TypeError: l’assegnazione del valore
// della proprietà di sola lettura
// non è consentita in modalità rigorosa
persona.nome = "bar";
[/code]
Si noti la linea numero 5. Se si indica il descrittore di proprietà writable come false facciamo in modo che la proprietà nome dell’oggetto persona sia di sola lettura. Qualsiasi tentativo di assegnare un valore a questa proprietà viene ignorata nella modalità non-ristretta, ma in modalità rigorosa viene generato un errore TypeError.
2. Modificare la configurazione di una proprietà non configurabile
[code lang=”javascript”] "use strict";
var persona = Object.create({}, {
nome: {
value: "foo",
writable: false,
configurable: false,
enumerable: true
}
});
// TypeError: non si può ridefinire una proprietà
// non configurabile (‘nome’)
Object.defineProperty(persona, "nome", {
value: "bar",
writable: true,
configurable: true,
enumerable: true
});
[/code]
Qui proviamo a modificare il descrittore di proprietà di un oggetto non configurabile. Ancora una volta, questo errore sarebbe passato inosservato in modalità non rigorosa, ma in modalità rigorosa restituisce un TypeError.
5. Scrivere nelle proprietà di sola lettura dell'accessore
Cercare di scrivere nelle proprietà dell’accessore quando non si è definito il setter, genera errori che in modalità senza restrizioni vengono ignorate:
[code lang=”javascript”] "use strict";
var persona = Object.create({}, {
nome: {
get: function() {
return "foo";
},
configurable: false,
enumerable: true
}
});
// TypeError
person.name = "bar";
[/code]
In questo caso, nome è una proprietà dell’accessore che non ha un metodo setter definito per l’editing. Se proviamo a cambiare il valore di questa proprietà avremo un errore in modalità rigorosa che non verrà visualizzato, invece, in modalità non rigorosa.
6. Non è possibile estendere oggetti non estensibili
Se si tenta di estendere un oggetto non estensibile otteniamo un errore in modalità rigorosa, mentre lo stesso caso in modalità non rigorosa viene ignorato:
[code lang=”javascript”] "use strict";
var persona = {
nome: "foo"
};
Object.preventExtensions(persona);
// TypeError: Impossibile creare una proprietà
// su un oggetto non estensibile
person.age = 10;
[/code]
7. Altre importanti restrizioni
Il codice in modalità Strict viene sottoposto a ulteriori restrizioni, anche se il suo uso è meno frequente.

  1. Le costanti numeriche non vengono interpretati come base ottale se iniziano con lo zero.
  2. Le istanze di variabili o funzioni nel codice eval in modalità Strict si producono nell’ambito locale al codice eval e non nell’anbito del codice chiamante. Ciò significa che il codice eval non può aggiungere nuovi identificatori nel contesto di esecuzione/portata del chiamante.
  3. arguments è inalterabile. Non possiamo estendere arbitrariamente l’oggetto arguments aggiungendo proprietà a nostro gradimento. Onestamente, non riesco a capire perché qualcuno dovrebbe provare a fare questo, ma probabilmente accade più spesso di quanto io credo, almeno secondo l’ECMA, perché sembra che si sono presi la briga d’indicare che questo non è possibile in modalità Strict!.
  4. arguments.callee e arguments.caller non si possono utilizzare in funzioni con la modalità rigorosa. Devo dire che questo problema non mi riguarda in particolare!
  5. Non è consentito creare definizioni duplicate di proprietà di un oggetto con il codice in modalità rigorosa. Il seguente esempio produce un errore:
    [code lang=”javascript”] "use strict";
    var o = Object.create({}, {
    nome: {
    value: "foo"
    },
    nome: {
    value: "bar"
    }
    });
    [/code]
    Questo codice produce un errore di sintassi con il messaggio “Multiple definitions of a property not allowed in strict mode” (non sono consentiti definizioni multipli di una proprietà in modalità rigorosa). Nella modalità senza restrizioni, o.name ritorna bar come valore.
  6. La chiamata a delete su una proprietà di ES5 la cui proprietà “configurable” è stato impostata a false genera un errore in modalità rigorosa. Si tratta di una variazione della restrizione già menzionata nel punto 4.
  7. La sentenza with di JavaScript non è supportata in modalità Strict.
  8. Con la modalità Strict non è possibile creare funzioni con nomi duplicati di parametri. Ancora una volta, sembra che va contro ogni logica che qualcuno voglia fare questo, ma a quanto pare è vero!
Buone pratiche
Qui ci sono alcune cose da tenere a mente quando si scrive del codice utilizzando la modalità rigorosa:

  1. Dal momento che la modalità Strict è una cosa abbastanza recente, è probabile che alcuni visitatori che aprono le vostre applicazioni web utilizzino un motore di JS che non riconosce la modalità Strict (a meno che gli utenti aggiornino volontariamente il proprio browser alla versione più recente, qualcosa che, potrei essere certo, non sarà possibile di ottenere). Ciò significa che tutto il codice si esequirà in modalità non rigorosa, anche se si include la politica Strict Mode. Conviene sempre testare il codice in modo non rigoroso per garantirci che tutto funzioni come previsto.
  2. Ma anche se la stragrande maggioranza degli utenti finali che utilizzano browser che non supportano la modalità rigorosa, è ancora ragionevole utilizzare la modalità rigorosa nell’ambiente di sviluppo, perché in queste condizioni siamo costretti a seguire le buone pratiche di programmazione JavaScript. Senza dubbio si finisce con il beneficio di avere dovuto assumere tali obblighi durante lo sviluppo e, naturalmente, non dimenticare di provare tutto in modo non rigoroso prima di metterlo in produzione.
  3. Abilitare la modalità rigorosa un po’ alla volta, invece di cercare di sistemare tutto in una sola volta. Se si dispone di un file JS, diciamo, 3.000 righe, probabilmente non è una buona idea aggiungere la direttiva “use strict” nella prima riga del file, in quanto le differenze semantiche tra le due modalità può portare a dei sottili bug e contingenze. Si dovrebbe fare in piccole porzioni a livello di funzione. Nel nuovo codice che si sviluppa si può usare in maniera generale.

Il mio consiglio è quello di sperimentare e di leggere sui vari tutorial per saperne di più sulla modalità Strict. A mio parere, è una delle migliori nuove caratteristiche che incorpora ES5. Credo che i seguenti link saranno utili per quanto riguarda la documentazione. E come si sà è tutto in inglese:

  • Demo con Modalità Strict;
  • IE Test Drive, dove è possibile scaricare la piattaforma preliminare di IE10;
  • Documentazione dello Strict Mode per lo sviluppo su IE10 Platform Preview;
  • Articolo su ES5 Strict Mode in Firefox 4, che ha delle buone informazioni sullo Strict Mode in generale;
  • Specifica ES5. Non è quello che si potrebbe chiamare una lettura emozionante, ma non c’è niente di meglio che fare riferimento alle specifiche per dotare di autorità a qualsiasi argomento!