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.
- Sono escluse alcune funzioni sintattiche e semantiche: non possiamo fare certe cose che sono ammesse negli altri casi.
- Modifica la semantica di alcune funzionalità: lo stesso codice funziona in modo diverso in modalità rigorosa e in modalità nonrigorosa.
- Restituisce più errori in alcuni casi: in situazioni in cui si ignorerebbe in modo trasparente o si eseguirebbe direttamente nella modalità non-ristretta.
- 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!
var prodotto = 0,
len = numero.length;
for(var i = 0; i < len; ++i) {
prdotto = prodotto * numero[i];
}
return prodotto;
}
[/code]
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.
alert("Guardami! Sono in modalità Strict!");
[/code]
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
script
>. Ad esempio:"use strict";
// Qui va il codice globale in modalità rigorosa
</script>
[/code]
[/code]
eval("// codice in modalità rigorosa");
[/code]
"use strict";
// codice in modalità rigorosa
}
[/code]
"use strict";
var bar = function () {
// codice in modalità rigorosa
};
bar();
}
[/code]
è importante notare inoltre che la restrizione non si estende alle chiamate sullo stack. Questo è un esempio:
// 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]
1. Gli identificatori devono essere dichiarati prima dell'assegnazione dei valori
// ReferenceError: variabile non definida modalità rigorosa
foo = 10;
[/code]
prodotto
code> non è scritta bene nell’istruzione di assegnazione che compare all’interno del ciclo for
.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]
// ritorna "true"
print(this === window);
}
foo();
[/code]
foo
senza fissare un oggetto di contesto esplicito, vale a dire, non facciamo la chiamata utilizzando un’espressione come questa:[/code]
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
:"use strict";
// ritorna "false"
print(this === window);
}
foo();
[/code]
var yield; // SyntaxError: atteso un identificatore
[/code]
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]
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
.
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]
TypeError
.
setter
, genera errori che in modalità senza restrizioni vengono ignorate:var persona = Object.create({}, {
nome: {
get: function() {
return "foo";
},
configurable: false,
enumerable: true
}
});
// TypeError
person.name = "bar";
[/code]
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.var persona = {
nome: "foo"
};
Object.preventExtensions(persona);
// TypeError: Impossibile creare una proprietà
// su un oggetto non estensibile
person.age = 10;
[/code]
- Le costanti numeriche non vengono interpretati come base ottale se iniziano con lo zero.
- Le istanze di variabili o funzioni nel codice
eval
in modalità Strict si producono nell’ambito locale al codiceeval
e non nell’anbito del codice chiamante. Ciò significa che il codiceeval
non può aggiungere nuovi identificatori nel contesto di esecuzione/portata del chiamante. arguments
è inalterabile. Non possiamo estendere arbitrariamente l’oggettoarguments
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!.arguments.callee
earguments.caller
non si possono utilizzare in funzioni con la modalità rigorosa. Devo dire che questo problema non mi riguarda in particolare!- 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";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,
var o = Object.create({}, {
nome: {
value: "foo"
},
nome: {
value: "bar"
}
});
[/code]o.name
ritornabar
come valore. - La chiamata a
delete
su una proprietà di ES5 la cui proprietà “configurable” è stato impostata afalse
genera un errore in modalità rigorosa. Si tratta di una variazione della restrizione già menzionata nel punto 4. - La sentenza
with
di JavaScript non è supportata in modalità Strict. - 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!
- 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.
- 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.
- 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!
Ancora nessun commento