From 30feb96f6084a2fb976a24ac01c1f4a054611b62 Mon Sep 17 00:00:00 2001 From: Florian Merz Date: Thu, 11 Feb 2021 14:47:54 +0100 Subject: unslug it: move --- .../a_re-introduction_to_javascript/index.html | 966 +++++++++++++++++++++ .../it/web/javascript/about_javascript/index.html | 57 ++ files/it/web/javascript/chiusure/index.html | 345 -------- files/it/web/javascript/closures/index.html | 345 ++++++++ .../javascript/cos\303\250_javascript/index.html" | 57 -- .../javascript/gestione_della_memoria/index.html | 197 ----- files/it/web/javascript/getting_started/index.html | 331 ------- .../index.html | 461 ---------- .../guida/dettagli_object_model/index.html | 727 ---------------- .../guida/espressioni_regolari/index.html | 647 -------------- files/it/web/javascript/guida/functions/index.html | 646 -------------- .../javascript/guida/grammar_and_types/index.html | 659 -------------- files/it/web/javascript/guida/index.html | 124 --- .../web/javascript/guida/introduzione/index.html | 140 --- .../guida/iteratori_e_generatori/index.html | 162 ---- .../guida/loops_and_iteration/index.html | 340 -------- .../control_flow_and_error_handling/index.html | 461 ++++++++++ .../guide/details_of_the_object_model/index.html | 727 ++++++++++++++++ files/it/web/javascript/guide/functions/index.html | 646 ++++++++++++++ .../javascript/guide/grammar_and_types/index.html | 659 ++++++++++++++ files/it/web/javascript/guide/index.html | 124 +++ .../web/javascript/guide/introduction/index.html | 140 +++ .../guide/iterators_and_generators/index.html | 162 ++++ .../guide/loops_and_iteration/index.html | 340 ++++++++ .../guide/regular_expressions/index.html | 647 ++++++++++++++ .../web/javascript/il_dom_e_javascript/index.html | 81 -- .../index.html | 391 --------- .../javascript_technologies_overview/index.html | 81 ++ .../it/web/javascript/memory_management/index.html | 197 +++++ .../reference/classes/constructor/index.html | 161 ++++ .../reference/classes/costruttore/index.html | 161 ---- .../reference/functions/arguments/index.html | 224 +++++ .../reference/functions/arrow_functions/index.html | 394 +++++++++ .../javascript/reference/functions/get/index.html | 154 ++++ .../web/javascript/reference/functions/index.html | 617 +++++++++++++ .../javascript/reference/functions/set/index.html | 214 +++++ .../arguments/index.html | 224 ----- .../arrow_functions/index.html | 394 --------- .../functions_and_function_scope/get/index.html | 154 ---- .../functions_and_function_scope/index.html | 617 ------------- .../functions_and_function_scope/set/index.html | 214 ----- .../global_objects/array/prototype/index.html | 203 ----- .../global_objects/object/prototype/index.html | 215 ----- .../global_objects/proxy/handler/apply/index.html | 119 --- .../global_objects/proxy/handler/index.html | 84 -- .../global_objects/proxy/proxy/apply/index.html | 119 +++ .../global_objects/proxy/proxy/index.html | 84 ++ .../global_objects/proxy/revocabile/index.html | 86 -- .../global_objects/proxy/revocable/index.html | 86 ++ .../global_objects/string/prototype/index.html | 179 ---- .../reference/operators/comma_operator/index.html | 105 +++ .../operators/conditional_operator/index.html | 171 ++++ .../operators/operator_condizionale/index.html | 171 ---- .../operators/operatore_virgola/index.html | 105 --- .../operators/operatori_aritmetici/index.html | 292 ------- .../reference/template_literals/index.html | 210 +++++ .../reference/template_strings/index.html | 210 ----- .../una_reintroduzione_al_javascript/index.html | 966 --------------------- 58 files changed, 8091 insertions(+), 9702 deletions(-) create mode 100644 files/it/web/javascript/a_re-introduction_to_javascript/index.html create mode 100644 files/it/web/javascript/about_javascript/index.html delete mode 100644 files/it/web/javascript/chiusure/index.html create mode 100644 files/it/web/javascript/closures/index.html delete mode 100644 "files/it/web/javascript/cos\303\250_javascript/index.html" delete mode 100644 files/it/web/javascript/gestione_della_memoria/index.html delete mode 100644 files/it/web/javascript/getting_started/index.html delete mode 100644 files/it/web/javascript/guida/controllo_del_flusso_e_gestione_degli_errori/index.html delete mode 100644 files/it/web/javascript/guida/dettagli_object_model/index.html delete mode 100644 files/it/web/javascript/guida/espressioni_regolari/index.html delete mode 100644 files/it/web/javascript/guida/functions/index.html delete mode 100644 files/it/web/javascript/guida/grammar_and_types/index.html delete mode 100644 files/it/web/javascript/guida/index.html delete mode 100644 files/it/web/javascript/guida/introduzione/index.html delete mode 100644 files/it/web/javascript/guida/iteratori_e_generatori/index.html delete mode 100644 files/it/web/javascript/guida/loops_and_iteration/index.html create mode 100644 files/it/web/javascript/guide/control_flow_and_error_handling/index.html create mode 100644 files/it/web/javascript/guide/details_of_the_object_model/index.html create mode 100644 files/it/web/javascript/guide/functions/index.html create mode 100644 files/it/web/javascript/guide/grammar_and_types/index.html create mode 100644 files/it/web/javascript/guide/index.html create mode 100644 files/it/web/javascript/guide/introduction/index.html create mode 100644 files/it/web/javascript/guide/iterators_and_generators/index.html create mode 100644 files/it/web/javascript/guide/loops_and_iteration/index.html create mode 100644 files/it/web/javascript/guide/regular_expressions/index.html delete mode 100644 files/it/web/javascript/il_dom_e_javascript/index.html delete mode 100644 files/it/web/javascript/introduzione_al_carattere_object-oriented_di_javascript/index.html create mode 100644 files/it/web/javascript/javascript_technologies_overview/index.html create mode 100644 files/it/web/javascript/memory_management/index.html create mode 100644 files/it/web/javascript/reference/classes/constructor/index.html delete mode 100644 files/it/web/javascript/reference/classes/costruttore/index.html create mode 100644 files/it/web/javascript/reference/functions/arguments/index.html create mode 100644 files/it/web/javascript/reference/functions/arrow_functions/index.html create mode 100644 files/it/web/javascript/reference/functions/get/index.html create mode 100644 files/it/web/javascript/reference/functions/index.html create mode 100644 files/it/web/javascript/reference/functions/set/index.html delete mode 100644 files/it/web/javascript/reference/functions_and_function_scope/arguments/index.html delete mode 100644 files/it/web/javascript/reference/functions_and_function_scope/arrow_functions/index.html delete mode 100644 files/it/web/javascript/reference/functions_and_function_scope/get/index.html delete mode 100644 files/it/web/javascript/reference/functions_and_function_scope/index.html delete mode 100644 files/it/web/javascript/reference/functions_and_function_scope/set/index.html delete mode 100644 files/it/web/javascript/reference/global_objects/array/prototype/index.html delete mode 100644 files/it/web/javascript/reference/global_objects/object/prototype/index.html delete mode 100644 files/it/web/javascript/reference/global_objects/proxy/handler/apply/index.html delete mode 100644 files/it/web/javascript/reference/global_objects/proxy/handler/index.html create mode 100644 files/it/web/javascript/reference/global_objects/proxy/proxy/apply/index.html create mode 100644 files/it/web/javascript/reference/global_objects/proxy/proxy/index.html delete mode 100644 files/it/web/javascript/reference/global_objects/proxy/revocabile/index.html create mode 100644 files/it/web/javascript/reference/global_objects/proxy/revocable/index.html delete mode 100644 files/it/web/javascript/reference/global_objects/string/prototype/index.html create mode 100644 files/it/web/javascript/reference/operators/comma_operator/index.html create mode 100644 files/it/web/javascript/reference/operators/conditional_operator/index.html delete mode 100644 files/it/web/javascript/reference/operators/operator_condizionale/index.html delete mode 100644 files/it/web/javascript/reference/operators/operatore_virgola/index.html delete mode 100644 files/it/web/javascript/reference/operators/operatori_aritmetici/index.html create mode 100644 files/it/web/javascript/reference/template_literals/index.html delete mode 100644 files/it/web/javascript/reference/template_strings/index.html delete mode 100644 files/it/web/javascript/una_reintroduzione_al_javascript/index.html (limited to 'files/it/web/javascript') diff --git a/files/it/web/javascript/a_re-introduction_to_javascript/index.html b/files/it/web/javascript/a_re-introduction_to_javascript/index.html new file mode 100644 index 0000000000..4dc4a484a7 --- /dev/null +++ b/files/it/web/javascript/a_re-introduction_to_javascript/index.html @@ -0,0 +1,966 @@ +--- +title: Una reintroduzione al Java Script (Tutorial JS) +slug: Web/JavaScript/Una_reintroduzione_al_JavaScript +translation_of: Web/JavaScript/A_re-introduction_to_JavaScript +--- +

Introduzione

+ +

Perchè una reintroduzione? Perchè  JavaScript ha la ragionevole pretesa di essere il linguaggio di programmazione più frainteso del mondo. Benchè spesso considerato ironicamente come un giocattolo, la sua ingannevole semplicità nasconde alcune potenti caratteristiche. JavaScript viene attualmente utilizzato da un numero incredibile di applicazioni di alto profilo, che mostrano come la conoscenza profonda di questa tecnologia sia un importante abilità per qualunque sviluppatore web.

+ +

È utile iniziare con un accenno alla storia del linguaggio. JavaScript fu creato nel 1995 da Brendan Eich, mentre lavorava come ingegnere presso Netscape, e rilasciata per la prima volta con Netscape 2 all'inizio del 1996. Originariamente doveva essere chiamato LiveScript, ma fu poi rinominato in Javacript per una fatalmente dannosa decisione di marketing che tentava di approfittare della popolarità del linguaggio Java della Sun Microsystem — nonostante abbiano molto poco in comune. Questa è stata una fonte di confusione da allora.

+ +

Diversi mesi dopo, Microsoft rilasciò JScript con Internet Explorer 3, un linguaggio che lavorava in modo simile a JavaScript ed era quasi del tutto compatibile con esso. Netscape sottomise il linguaggio alla Ecma International, un'organizzazione europea di standardizzazione, che porta alla nascita della prima edizione degli standard ECMAScript. Lo standard ricevette un significativo aggiornamento come ECMAScript edition 3 nel 1999, ed è rimasto più o meno stabile da allora. La quarta edizione fu abbandonata a causa delle differenze di vedute sulla complessità del linguaggio. Molte parti della quarta edizione formano la base del nuovo ECMAScript edizione 5, pubblicato nel dicembre del 2009, e per la sesta edizione pubblicata a giugno 2015.

+ +

Diversamente dalla maggior parte dei linguaggi di programmazione, il linguaggio JavaScript non ha il concetto di input e output. È stato concepito per essere eseguito come linguaggio di scripting in un ambiente ospite, ed è responsabilità dell'ambiente ospite fornire meccanismi per comunicare con il mondo esterno. L'ambiente ospite più comune è il browser, ma interpreti JavaScript possono essere trovati anche in Adobe Acrobat, Photoshop, motore Widget di Yahoo! , e addirittura in ambienti lato server o in desktop environment come GNOME (una delle GUI più popolari per i sistemi GNU/Linux) e altri ancora.

+ +

Panoramica

+ +

JavaScript è un linguaggio dinamico orientato agli oggetti; esso ha tipi e operatori, oggetti nucleo, e metodi. La sua sintassi deriva dai linguaggi Java e C, quindi molte strutture utilizzate da questi linguaggi ricorrono anche in JavaScript. Una delle differenze chiave è che JavaScript non ha classi; invece, la funzionalità di classe è realizzata dai prototipi oggetto. L'altra differenza principale è che le funzioni sono oggetti, dando alle funzioni la capacità di mantenere codice eseguibile ed essere passate in giro come ogni altro oggetto.

+ +

Cominciamo guardando il blocco di costruzione di qualsiasi linguaggio: i tipi. I programmmi JavaScript manipolano valori, e tutti quei valori appartengono ad un tipo. I tipi JavaScript sono:

+ + + +

... oh, e Undefined (indefiniti) e Null (nulli), che sono leggermente strani. E gli Array, che sono un tipo speciale di oggetto. E Date ed Espressioni regolari, che sono oggetti che si ottengono gratuitamente. E per essere tecnicamente precisi, le funzioni sono solo un tipo speciale di oggetto. Quindi il diagramma dei tipi somiglia più a questo:

+ + + +

E ci sono anche alcuni tipi nativi di Errori. Comunque, le cose sono molto più semplici se ci atteniamo al primo diagramma

+ +

Numeri

+ +

I numeri in JavaScript sono in formato 64-bit a doppia precisione valore del IEEE 754, secondo le specifiche. Questo ha qualche interessante conseguenza. Non esiste una cosa come un intero in JavaScript, quindi bisogna stare un pò attenti con la vostra aritmetica, se siete abituati alla matematica in C o Java. Stare attenti a cose come:

+ +
0.1 + 0.2 == 0.30000000000000004
+
+ +

In pratica, i valori interi sono trattati come int a 32-bit (e sono memorizzati in questo modo in alcune implementazioni dei browser), che può essere importante per operazioni in bit. Per dettagli, consulta La Guida Completa sui Numeri JavaScript.

+ +

Gli operatori numerici standard sono supportati, incluso addizione, sottrazione, modulo (o resto) aritmetico e così via. Vi sono anche oggetti nativi che non sono stati menzionati prima, chiamati Math per trattare funzioni matematiche più avanzate e costanti:

+ +
Math.sin(3.5);
+var d = Math.PI * r * r;
+
+ +

E' possibile convertire una stringa in un intero utilizzando la funzione nativa parseInt(). Questo prende la base per la conversione come secondo argomento opzionale, che si dovrebbe fornire sempre:

+ +
> parseInt("123", 10)
+123
+> parseInt("010", 10)
+10
+
+ +

Se non si fornisce la base, si possono ricevere risultati inattesi:

+ +
> parseInt("010")
+8
+
+ +

Questo succede perchè la funzione parseInt ha deciso di trattare la stringa come un ottale a causa del primo 0.

+ +

Se si vuole convertire un numero binario in un intero, basta cambiare la base:

+ +
> parseInt("11", 2)
+3
+
+ +

Similmente, è possibile analizzare numeri in virgola mobile usando la funzione nativa parseFloat() che utilizza sempre la base 10 diversamente dalla cugina parseInt().

+ +

E' inoltre possibile utilizzare l'operatore unario + per convertire valori in numeri:

+ +
> + "42"
+42
+
+ +

Un valore speciale chiamato NaN (abbreviazione per "Not a Number" - Non un Numero) viene restituita se la stringa non è numerica:

+ +
> parseInt("hello", 10)
+NaN
+
+ +

Il NaN è tossico: se viene fornito come input a qualsiasi operazione matematica, il risultato sarà anch'esso NaN:

+ +
> NaN + 5
+NaN
+
+ +

E' possibile verificare se NaN usando la funzione nativa isNaN():

+ +
> isNaN(NaN)
+true
+
+ +

Anche JavaScript ha i valori speciali Infinity-Infinity:

+ +
> 1 / 0
+Infinity
+> -1 / 0
+-Infinity
+
+ +

E' possibile analizzare i valori Infinity, -Infinity e NaN usando la funzione nativa isFinite():

+ +
> isFinite(1/0)
+false
+> isFinite(-Infinity)
+false
+> isFinite(NaN)
+false
+
+ +
Nota: Le funzioni parseInt() e parseFloat() analizzano una stringa finchè raggiungono un carattere che è non è valido per il formato numerico specificato, quindi restituiscono il numero analizzato fino a quel punto. Tuttavia l'operatore "+" converte semplicemente la stringa a NaN se è presente in essa qualche carattere invalido. E' sufficiente provare ad eseguire l'analisi della stringa "10.2abc" con ogni metodo da soli utilizzando la console e sarà possibile capire meglio le differenze.
+ +

Stringhe

+ +

Le stringhe in JavaScript sono sequenze di caratteri. Più precisamente, sono sequenze di Caratteri Unicode, con ogni carattere rappresentato da un numero a 16-bit. Questa dovrebbe essere una buona notizia per tutti coloro che hanno avuto a che fare con l'internazionalizzazione.

+ +

Se si vuole rappresentare un singolo carattere, occorre semplicemente utilizzare una stringa di lunghezza 1.

+ +

Per trovare la lunghezza di una stringa, accedere la sua proprietà length:

+ +
> "hello".length
+5
+
+ +

Ecco il nostro primo assaggio degli oggetti JavaScript! E' stato menzionato che le stringhe sono anch'esse oggetti? Ed hanno anche metodi:

+ +
> "hello".charAt(0)
+h
+> "hello, world".replace("hello", "goodbye")
+goodbye, world
+> "hello".toUpperCase()
+HELLO
+
+ +

Altri tipi

+ +

JavaScript distingue tra null, che è un oggetto di tipo 'object' che indica un mancanza deliberata di valore, e undefined, che è un oggetto di tipo 'undefined' che indica un valore non inizializzato — ossia un valore che non è stato ancora assegnato. Parleremo delle variabili più avanti, ma in JavaScript è possibile dichiarare una variabile senza assegnarle un valore. Facendo questo, il tipo della variabile creata sarà undefined.

+ +

JavaScript ha il tipo booleano, con possibili valori true (vero) e false (falso) (entrambi i quali sono parole chiave). Qualunque valore può essere convertito in booleano seguendo le seguenti regole:

+ +
    +
  1. false, 0, la stringa vuota (""), NaN, null, e undefined diventano tutti false
  2. +
  3. tutti gli altri valori diventano true
  4. +
+ +

E' possibile eseguire questa conversione esplicitamente usando la funzione Boolean():

+ +
> Boolean("")
+false
+> Boolean(234)
+true
+
+ +

Tuttavia, questo raramente è necessario, JavaScript eseguirà silenziosamente la conversione quando si aspetta un booleano, così come in una istruzione  if (vedi sotto). Per questa ragione, a volte si parla semplicemente di "valori veri" e "valori falsi" valori significativi che diventano true e false, rispettivamente, quando convertiti in booleani. In alternativa, tali valori possono essere chiamati "truthy" e "falsy", rispettivamente.

+ +

Le operazioni booleane come && (and logico), || (or logico), e ! (not logico) sono supportate; vedi sotto.

+ +

Variabili

+ +

Le nuove varibili sono dichiarate in JavaScript utilizzando la parola chiave var:

+ +
var a;
+var name = "simon";
+
+ +

Se la variabile viene dichiarata senza assegnarle un valore, il suo tipo sarà undefined

+ +

Una differenza importante rispetto ad altri linguaggi come Java è che in JavaScript, i blocchi non hanno ambito; solo le funzioni hanno ambito. Quindi se una variabile viene definita utilizzando var in una istruzione composta (ad esempio all'interno di una struttura di controllo if), essa sarà visibile da parte dell'intera funzione.

+ +

Operatori

+ +

Gli operatori numerici in JavaScript sono +, -, *, /% - che è l'operatore per il resto. I valori sono assegnanti usando =, e vi sono anche le istruzioni di assegnamento composte tipo += e -=. Questi comprimono la forma x = x operatore y.

+ +
x += 5
+x = x + 5
+
+ +

E' possibile utilizzare ++ e -- per incrementare e decrementare rispettivamente. Questi possono essere usati come operatori prefissi o postfissi.

+ +

L'operatore + compie anche la concatenazione di stringhe:

+ +
> "hello" + " world"
+hello world
+
+ +

Se si somma una stringa ad un numero (o ad un altro valore) tutto viene convertito dalla prima stringa. Questo esempio potrebbe aiutare a chiarire il tutto:

+ +
> "3" + 4 + 5
+345
+> 3 + 4 + "5"
+75
+
+ +

Sommare una stringa vuota ad un altro tipo è un utile maniera per convertirlo.

+ +

I confronti in JavaScript possono essere eseguiti usando <, >, <= e >=. Essi funzionano sia per le stringhe che per i numeri. L'uguaglianza è un pochino meno lineare. L'operatore di doppio uguale esegue la coercizione di tipo se viene eseguita tra tipi differenti, con a volte risultati interessanti:

+ +
> "dog" == "dog"
+true
+> 1 == true
+true
+
+ +

Per evitare la coercizione di tipo, si utilizza l'operatore triplo uguale:

+ +
> 1 === true
+false
+> true === true
+true
+
+ +

Vi sono anche gli operatori !=!== .

+ +

JavaScript ha inoltre le operazioni bit per bit. Se si desidera utilizzarle, sono lì.

+ +

Strutture di controllo

+ +

JavaScript ha una serie di strutture di controllo simili agli altri linguaggi della famiglia del C. Le istruzioni condizionali sono supportate da if e else (se e altrimenti) che possono essere concatenati insieme se desiderato:

+ +
var name = "kittens";
+if (name == "puppies") {
+  name += "!";
+} else if (name == "kittens") {
+  name += "!!";
+} else {
+  name = "!" + name;
+}
+name == "kittens!!"
+
+ +

JavaScript ha il ciclo while ed il ciclo do-while. Il primo è utile per un ciclo basico; il secondo per i cicli che si vuole essere sicuri che vengano eseguiti almeno una volta:

+ +
while (true) {
+  // an infinite loop!
+}
+
+var input;
+do {
+  input = get_input();
+} while (inputIsNotValid(input))
+
+ +

Il ciclo for in JavaScript è lo stesso che in C e Java: esso permette di fornire le informazioni di controllo per il ciclo in una linea singola.

+ +
for (var i = 0; i < 5; i++) {
+  // Will execute 5 times
+}
+
+ +

Gli operatori &&(and logico) e ||(or logico) usano un corto-circuito logico, questo significa che quando vengono eseguiti il secondo operando è dipendente dal primo. Questo è utile per verificare oggetti nulli prima di accedere ai loro attributi:

+ +
var name = o && o.getName();
+
+ +

Oppure per impostare valori di default:

+ +
var name = otherName || "default";
+
+ +

JavaScript ha un operatore ternario per espressioni condizionali:

+ +
var allowed = (age > 18) ? "yes" : "no";
+
+ +

L'istruzione switch può essere utilizzata per più diramazioni sulla base di un numero o una stringa:

+ +
switch(action) {
+    case 'draw':
+        drawit();
+        break;
+    case 'eat':
+        eatit();
+        break;
+    default:
+        donothing();
+}
+
+ +

Se non viene inserita l'istruzione break, l'esecuzione "naufragherà" nel prossimo livello. Questo è raramente il risultato voluto — in realtà vale la pena in particolare inserire un etichettatura deliberatamente con un commento, se vi vuole aiutare il debug:

+ +
switch(a) {
+    case 1: // fallthrough
+    case 2:
+        eatit();
+        break;
+    default:
+        donothing();
+}
+
+ +

La clausula default è opzionale. Si possono avere espressioni sia nello switch sia che nel case se si vuole; i confronti avvengono tra i due con l'operatore ===:

+ +
switch(1 + 3) {
+    case 2 + 2:
+        yay();
+        break;
+    default:
+        neverhappens();
+}
+
+ +

Oggetti

+ +

Gli oggetti JavaScript sono semplicemente collezioni di coppie nome-valore. Come tali, essi sono simili a:

+ + + +

Il fatto che questa struttura dati è così diffusa è la prova della sua versatilità. Dal momento che tutto (barra i tipi base) in JavaScript è un oggetto, qualunque programma JavaScript implica naturalmente un grande ricorso alla ricerca nelle tabelle hash. E' buona cosa che siano così veloci!

+ +

La parte "name" è una stringa JavaScript, mentre il valore può essere qualunque valore JavaScript — incluso più oggetti. Questo permette di costruire strutture dati di complessità arbitraria.

+ +

Ci sono due modalità di base per creare un oggetto vuoto:

+ +
var obj = new Object();
+
+ +

E:

+ +
var obj = {};
+
+ +

Entrambe sono semanticamente equivalenti; la seconda è chiamata sintassi letterale dell'oggetto, ed è più conveniente. Questa sintassi è anche la base del formato JSON e dovrebbe essere preferita ogni volta.

+ +

Una volta creato si può accedere alle proprietà di un oggetto in una o due modalità:

+ +
obj.name = "Simon";
+var name = obj.name;
+
+ +

E...

+ +
obj["name"] = "Simon";
+var name = obj["name"];
+
+ +

Anche queste sono semanticamente equivalenti. Il secondo metodo ha il vantaggio che il nome della proprietà viene fornito come stringa, che significa che può essere calcolato durante l'esecuzione e l'utilizzo di questo metodo evita che siano applicate ottimizzazioni del motore JavaScript e minifier. Può essere inoltre usato per impostare o ottenere proprietà con nomi che sono parole riservate:

+ +
obj.for = "Simon"; // Syntax error, because 'for' is a reserved word
+obj["for"] = "Simon"; // works fine
+
+ +

La sintassi dell'oggetto letterale può essere usata per inizializzare un oggetto nella sua interezza:

+ +
var obj = {
+    name: "Carrot",
+    "for": "Max",
+    details: {
+        color: "orange",
+        size: 12
+    }
+}
+
+ +

Attributi di accesso possono essere concatenati:

+ +
> obj.details.color
+orange
+> obj["details"]["size"]
+12
+
+ +

Array (matrici)

+ +

Gli array in JavaScript sono un tipo speciale di oggetto. Essi funzionano in modo molto simile agli oggetti regolari (si può accedere alle proprietà numeriche solo usando la sintassi []) ma hanno una proprietà magica chiamata 'length'. Questa è sempre uno in più dell'indice massimo dell'array.

+ +

Il vecchio metodo per creare un array è il seguente:

+ +
> var a = new Array();
+> a[0] = "dog";
+> a[1] = "cat";
+> a[2] = "hen";
+> a.length
+3
+
+ +

Una notazione più conveniente è l'utilizzo di una array letterale:

+ +
> var a = ["dog", "cat", "hen"];
+> a.length
+3
+
+ +

Lasciare una virgola finale al termine di un array letterale è incompatibile tra i browser, quindi non fatelo.

+ +

Nota che array.length non è necessariamente il numero di elementi nell'array. Considera il seguente esempio:

+ +
> var a = ["dog", "cat", "hen"];
+> a[100] = "fox";
+> a.length
+101
+
+ +

Ricorda — la lunghezza dell'array è uno più dell'indice più alto.

+ +

Se si interroga un indice dell'array inesistente, la risposta sarà undefined:

+ +
> typeof a[90]
+undefined
+
+ +

Se si prende in considerazione quanto sopra, è possibile scorrere un array utilizzando le istruzioni seguenti:

+ +
for (var i = 0; i < a.length; i++) {
+    // Do something with a[i]
+}
+
+ +

Questo è un po' inefficiente, poichè si ricerca la proprietà length una volta ogni ciclo. Un possibile miglioramento è questo:

+ +
for (var i = 0, len = a.length; i < len; i++) {
+    // Do something with a[i]
+}
+
+ +

Un modo ancora più simpatico è questo:

+ +
for (var i = 0, item; item = a[i++];) {
+    // Do something with item
+}
+
+ +

Qui si stanno impostando due variabili. L'assegnamento nella parte centrale del ciclo for è anche verificato per veridicità — se ha successo, il ciclo continua. Siccome i viene incrementato ogni volta, gli elementi dalla matrice saranno assegnati all'elemento in ordine sequenziale. Il ciclo termina quando viene trovato un elemento "falso" (come un undefined).

+ +

Nota che questo trucco dovrebbe essere usato solo per gli array che sappiamo non contengano valori "falsi" (array di oggetti o nodi del DOM per esempio). Se si effettua l'iterazione dei dati numerici che potrebbero includere uno 0, o dati stringa che potrebbero includere la stringa vuota, è necessario utilizza l'idioma i, len in sostituzione.

+ +

Un altro modo per iterare è di utilizzare il ciclo for...in. Nota che se vengono aggiunte nuove proprietà all' Array.prototype, saranno anch'esse iterate da questo ciclo:

+ +
for (var i in a) {
+  // Do something with a[i]
+}
+
+ +

Se si vuole accodare un elemento all'array, la maniera più sicura per farlo è questa:

+ +
a[a.length] = item;                 // same as a.push(item);
+
+ +

Poichè a.length è uno in più dell'indice più alto, si può essere sicuri che l'elemento sarà assegnato ad una posizione vuota alla fine dell'array.

+ +

Gli arrays nascono con alcuni metodi:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Method nameDescription
a.toString()
a.toLocaleString()
a.concat(item[, itemN])Restituisce un nuovo array con gli elementi aggiunti ad esso.
a.join(sep)
a.pop()Rimuove e restituisce l'ultimo elemento.
a.push(item[, itemN])Push aggiunge uno o più elementi alla fine.
a.reverse()
a.shift()
a.slice(start, end)Restituisce un sub-array.
a.sort([cmpfn])Riceve una funzione di comparazione opzionale.
a.splice(start, delcount[, itemN])Permette di modificare un array cancellando una sezione e sostituendola con più elementi.
a.unshift([item])Antepone elementi all'inizio dell'array
+ +

Funzioni

+ +

Insieme con gli oggetti, le funzioni sono la componente principale nella comprensione di JavaScript. La funzione più elementare non potrebbe essere molto più semplice:

+ +
function add(x, y) {
+    var total = x + y;
+    return total;
+}
+
+ +

Ciò dimostra tutto quello che c'è da sapere sulle funzioni di base. Una funzione JavaScript può ricevere 0 (zero) o più parametri. Il corpo della funzione può contenere tutte le istruzioni che si desidera, e può dichiarare le proprie variabili che saranno locali alla stessa. L'istruzione return può essere usata per restituire un valore in qualsiasi momento, terminando la funzione. Se non viene utilizzata l'istruzione return (oppure viene restituito un valore vuoto o indefinito), JavaScript restituisce undefined.

+ +

I parametri denominati risultano più simili alle linee guida di ogni altra cosa. È possibile chiamare una funzione senza passare i parametri che si aspetta, nel qual caso saranno impostati su undefined.

+ +
> add()
+NaN // You can't perform addition on undefined
+
+ +

È anche possibile passare più argomenti di quelli che la funzione si aspetta:

+ +
> add(2, 3, 4)
+5 // added the first two; 4 was ignored
+
+ +

Questo può sembrare un po' sciocco, ma le funzioni hanno accesso a una variabile aggiuntiva all'interno del loro corpo chiamata argomenti, che è un oggetto simil array che detiene tutti i valori passati alla funzione. Riscriviamo la funzione somma per ricevere tutti i valori che vogliamo:

+ +
function add() {
+    var sum = 0;
+    for (var i = 0, j = arguments.length; i < j; i++) {
+        sum += arguments[i];
+    }
+    return sum;
+}
+
+> add(2, 3, 4, 5)
+14
+
+ +

Questo, però, non è realmente più utile che scrivere 2 + 3 + 4 + 5. Creiamo una funzione per il calcolo della media:

+ +
function avg() {
+    var sum = 0;
+    for (var i = 0, j = arguments.length; i < j; i++) {
+        sum += arguments[i];
+    }
+    return sum / arguments.length;
+}
+> avg(2, 3, 4, 5)
+3.5
+
+ +

Questa è piuttosto utile, ma introduce un nuovo problema. La funzione avg() riceve una lista di argomenti separati da una virgola — ma cosa succede se si vuole trovare la media di un array? Si potrebbe semplicemente riscrivere la funzione come segue:

+ +
function avgArray(arr) {
+    var sum = 0;
+    for (var i = 0, j = arr.length; i < j; i++) {
+        sum += arr[i];
+    }
+    return sum / arr.length;
+}
+> avgArray([2, 3, 4, 5])
+3.5
+
+ +

Ma sarebbe bello essere in grado di riutilizzare la funzione che abbiamo già creato. Fortunatamente, JavaScript permette di chiamare una funzione e di chiamarla con un array arbitrario di argomenti, usando il metodo apply() di qualunque oggetto di funzione.

+ +
> avg.apply(null, [2, 3, 4, 5])
+3.5 is the array to use as arguments; the first will be discussed later on. This emphasizes the fact that functions are objects too.
+
+ +

JavaScript permette la creazione di funzioni anonime.

+ +
var avg = function() {
+    var sum = 0;
+    for (var i = 0, j = arguments.length; i < j; i++) {
+        sum += arguments[i];
+    }
+    return sum / arguments.length;
+}
+
+ +

Questa è semanticamente equivalente alla forma function avg(). Essa è estremamente potente, in quando consente di definire una funzione ovunque si possa normalmente inserire un espressione. Questo consente ogni sorta di trucco intelligente. Ecco un modo di "nascondere" alcune variabili locali - come in un ambito di blocco in C:

+ +
> var a = 1;
+> var b = 2;
+> (function() {
+    var b = 3;
+    a += b;
+})();
+> a
+4
+> b
+2
+
+ +

JavaScript consente di chiamare le funzioni in modo ricorsivo. Ciò è particolarmente utile per affrontare le strutture ad albero, come ad esempio nel DOM del browser.

+ +
function countChars(elm) {
+    if (elm.nodeType == 3) { // TEXT_NODE
+        return elm.nodeValue.length;
+    }
+    var count = 0;
+    for (var i = 0, child; child = elm.childNodes[i]; i++) {
+        count += countChars(child);
+    }
+    return count;
+}
+
+ +

Questo mette in evidenza un potenziale problema con le funzioni anonime: come fare a richiamarle ricorsivamente se non hanno un nome? La risposta si trova con l'oggetto arguments, che oltre ad agire come una lista di argomenti, fornisce anche una propietà chiamata arguments.callee. L'uso della arguments.callee è deprecato e anche disabilitato nel modo strict (rigoroso). In sostituzione si devono utilizzare le "funzioni anonime nominate" come di seguito:

+ +
var charsInBody = (function counter(elm) {
+    if (elm.nodeType == 3) { // TEXT_NODE
+        return elm.nodeValue.length;
+    }
+    var count = 0;
+    for (var i = 0, child; child = elm.childNodes[i]; i++) {
+        count += counter(child);
+    }
+    return count;
+})(document.body);
+
+ +

Il nome fornito a una funzione anonima come sopra è (o almeno dovrebbe essere) disponibile solo nell'ambito stesso della funzione. Questo consente sia più ottimizzazioni da svolgere da parte del motore sia un codice più leggibile.

+ +

Oggetti personalizzati

+ +
Nota: Per una discussione più dettagliata della programmazione orientata agli oggetti, vedi Introduzione a JavaScript Orientato agli Oggetti.
+ +

Nella programmazione Object Oriented classica, gli oggetti sono collezioni di dati e metodi che operano su quei dati. JavaScript è un linguaggio basato su prototipi e non contiene l'istruzione classe, così come si trova in C++ o Java. (Questo a volte è fonte di confusione per i programmatori abituati ai linguaggi con una dichiarazione di classe.) Al suo posto, JavaScript usa le funzioni come classi. Consideriamo un oggetto persona con i campi nome e cognome. Ci sono due modi di visualizzare il nominativo: come  "nome cognome" o come "cognome, nome". Usando le funzioni e gli oggetti che abbiamo visto in precedenza, ecco un modo di ottenere il risultato voluto:

+ +
function makePerson(first, last) {
+    return {
+        first: first,
+        last: last
+    }
+}
+function personFullName(person) {
+    return person.first + ' ' + person.last;
+}
+function personFullNameReversed(person) {
+    return person.last + ', ' + person.first
+}
+> s = makePerson("Simon", "Willison");
+> personFullName(s)
+Simon Willison
+> personFullNameReversed(s)
+Willison, Simon
+
+ +

Questo funziona, ma è piuttosto brutto. Si finisce con dozzine di funzioni nel namespace globale. Ciò di cui abbiamo veramente bisogno è un modo per associare una funzione ad un oggetto. Dal momento che le funzioni sono oggetti, questo è facile:

+ +
function makePerson(first, last) {
+    return {
+        first: first,
+        last: last,
+        fullName: function() {
+            return this.first + ' ' + this.last;
+        },
+        fullNameReversed: function() {
+            return this.last + ', ' + this.first;
+        }
+    }
+}
+> s = makePerson("Simon", "Willison")
+> s.fullName()
+Simon Willison
+> s.fullNameReversed()
+Willison, Simon
+
+ +

Vi è qualcosa che non abbiamo visto prima: la parola chiave 'this'. Usata dentro una funzione, 'this' si riferisce all'oggetto corrente. Che cosa significa in realtà è specificato dal modo in cui è stata chiamata tale funzione. Se è stata chiamata usando la notazione col punto o la notazione con le parentesi su un oggetto, questo oggetto diventa 'this'. Se la notazione col punto non è stata usata per la chiamata, 'this' si riferisce all'oggetto globale. Questa è una causa di errori frequente. Ad esempio:

+ +
> s = makePerson("Simon", "Willison")
+> var fullName = s.fullName;
+> fullName()
+undefined undefined
+
+ +

Quando chiamiamo fullName(), 'this' è legata all'oggetto globale. Dato che non ci sono variabili globali chiamate first o last riceviamo undefined per ognuna delle due.

+ +

Possiamo prendere il vantaggio della parola chiave 'this' per migliorare la nostra funzione makePerson:

+ +
function Person(first, last) {
+    this.first = first;
+    this.last = last;
+    this.fullName = function() {
+        return this.first + ' ' + this.last;
+    }
+    this.fullNameReversed = function() {
+        return this.last + ', ' + this.first;
+    }
+}
+var s = new Person("Simon", "Willison");
+
+ +

Abbiamo introdotto un'altra parola chiave: 'new'. new è fortemente correlata a 'this'. Quello che fa è creare un oggetto vuoto nuovo di zecca e quindi chiamare la funzione specificata, con 'this' impostato sul nuovo oggetto. Le funzioni che sono disegnate per essere richiamate dalla 'new' sono chiamate costruttori. La pratica comune è di nominare queste funzioni con la prima lettera maiuscola in modo da ricordarsi di chiamarle con il new.

+ +

I nostri oggetti persona stanno migliorando, ma vi sono ancora alcuni lati brutti in loro. Ogni volta che si crea un oggetto persona, stiamo creando due nuovi oggetti funzione all'interno di esso - non sarebbe meglio se il codice fosse stato condiviso?

+ +
function personFullName() {
+    return this.first + ' ' + this.last;
+}
+function personFullNameReversed() {
+    return this.last + ', ' + this.first;
+}
+function Person(first, last) {
+    this.first = first;
+    this.last = last;
+    this.fullName = personFullName;
+    this.fullNameReversed = personFullNameReversed;
+}
+
+ +

Così va meglio: stiamo creando i metodi della funzione una sola volta, e assegnando ad essi i riferimenti all'interno del costruttore. Possiamo fare di meglio? La risposta è sì:

+ +
function Person(first, last) {
+    this.first = first;
+    this.last = last;
+}
+Person.prototype.fullName = function() {
+    return this.first + ' ' + this.last;
+}
+Person.prototype.fullNameReversed = function() {
+    return this.last + ', ' + this.first;
+}
+
+ +

Person.prototype è un oggetto condiviso da tutte le istanze di Person. Essa fa parte di una catena di ricerca (che ha un nome speciale, "catena di prototipi"): ogni volta che si tenta di accedere ad una proprietà di Person che non è impostata, JavaScript controllerà Person.prototype per vedere se quella proprietà esiste al suo interno. Come risultato, qualsiasi valore assegnato a Person.prototype diventa disponibile a tutte le istanze del costruttore per mezzo dell'oggetto this.

+ +

Si tratta di uno strumento incredibilmente potente. JavaScript consente di modificare il prototipo di qualcosa in qualsiasi momento nel programma, il che significa che è possibile aggiungere metodi extra per gli oggetti esistenti in fase di esecuzione:

+ +
> s = new Person("Simon", "Willison");
+> s.firstNameCaps();
+TypeError on line 1: s.firstNameCaps is not a function
+> Person.prototype.firstNameCaps = function() {
+    return this.first.toUpperCase()
+}
+> s.firstNameCaps()
+SIMON
+
+ +

È interessante notare che è anche possibile aggiungere le cose al prototipo degli oggetti nativi JavaScript. Aggiungiamo un metodo a String che restituisca la stringa al contrario:

+ +
> var s = "Simon";
+> s.reversed()
+TypeError on line 1: s.reversed is not a function
+> String.prototype.reversed = function() {
+    var r = "";
+    for (var i = this.length - 1; i >= 0; i--) {
+        r += this[i];
+    }
+    return r;
+}
+> s.reversed()
+nomiS
+
+ +

Il nostro nuovo metodo funziona anche con le stringhe letterali!

+ +
> "This can now be reversed".reversed()
+desrever eb won nac sihT
+
+ +

Come detto prima, il prototipo fa parte di una catena. La radice di questa catena è Object.prototype, i cui metodi includono toString() — è questo metodo che viene chiamato quando si tenta di rappresentare un oggetto come una stringa. Questo è utile per verificare il nostro oggetto Person:

+ +
> var s = new Person("Simon", "Willison");
+> s
+[object Object]
+> Person.prototype.toString = function() {
+    return '<Person: ' + this.fullName() + '>';
+}
+> s
+<Person: Simon Willison>
+
+ +

Ricordate come avg.apply() aveva un primo argomento nullo? Possiamo riesaminarlo adesso. Il primo argomento di apply() è l'oggetto che dovrebbe essere trattato come 'this'. Per esempio, qui una semplice implementazione di 'new':

+ +
function trivialNew(constructor) {
+    var o = {}; // Create an object
+    constructor.apply(o, arguments);
+    return o;
+}
+
+ +

Questa non è un'esatta replica di new in quanto non imposta la catena del prototipo (sarebbe difficile da illustrare). Non è una cosa che si usa molto spesso, ma è utile conoscerla. In questo snippet, ...args (puntini inclusi) è chiamato il "rest arguments" – come indicato dal nome, e contiene il resto degli argomenti. Per ora, questa "feature" è sperimentale e solo disponibile in Firefox; è raccomandato attaccare gli arguments per ora.

+ +

Chiamare

+ +
var bill = trivialNew(Person, "William", "Orange");
+ +
+ +

è dunque quasi equivalente a

+ +
var bill = new Person("William", "Orange");
+ +
+ +

apply() ha una funzione sorella dal nome call, che di nuovo ti consente di impostare 'this' ma prende una lista espansa di argomenti invece che un array.

+ +
function lastNameCaps() {
+    return this.last.toUpperCase();
+}
+var s = new Person("Simon", "Willison");
+lastNameCaps.call(s);
+// Is the same as:
+s.lastNameCaps = lastNameCaps;
+s.lastNameCaps();
+
+ +

Inner functions

+ +

In JavaScript è consentito dichiarare una funzione all'interno di un'altra funzione. Lo abbiamo già visto prima, nel caso della precedente funzione makePerson(). Un dettaglio importante di funzioni innestate in JavaScript è che esse possono accedere alle variabili della funzione di livello superiore:

+ +
function betterExampleNeeded() {
+    var a = 1;
+    function oneMoreThanA() {
+        return a + 1;
+    }
+    return oneMoreThanA();
+}
+
+ +

Ciò è di grande utilità per scrivere codice più manutenibile. Se una funzione dipende da una o due altre funzioni che non sono usate in nessuna altra parte del tuo codice, è possibile nidificare quelle funzioni di utilità dentro la funzione che sarà chiamata dall'esterno. Questo riduce il numero di funzioni che si trovano nel "global scope", che è sempre una buona cosa.

+ +

Questa è anche una grande cosa contro il richiamo di variabili globali. Quando si scrive codice complesso si è spesso tentati di usare variabili globali per condividere i valori tra più funzioni — e ciò rende il codice difficile da manutenere. Le funzioni nidificate possono condividere le variabili della funzione padre, così è possibile usare questo meccanismo per accoppiare le funzioni quando serve, senza contaminare il tuo namespace globale — rendi locali le variabili globali per piacere. Questa tecnica dovrebbe essere usata con parsimonia, ma è una capacità utile da avere.

+ +

Closures

+ +

Questo ci porta ad una delle più potenti astrazioni che JavaScript ha da offrire — ma anche quella che può generare più confusione. Cosa fa questo codice sotto?

+ +
function makeAdder(a) {
+    return function(b) {
+        return a + b;
+    }
+}
+x = makeAdder(5);
+y = makeAdder(20);
+x(6)
+?
+y(7)
+?
+
+ +

Il nome della funzione makeAdder dovrebbe essere esplicito: essa può creare delle nuove funzioni 'adder', che, se chiamate con un determinato argomento, lo addizionano all'argomento con il quale sono state create.

+ +

Quello che sta avvenendo qui è praticamente la stessa cosa vista precedentemente con le "inner functions": una funzione definita dentro un'altra funzione ha accesso alle variabili della funzione esterna. La sola differenza è che in questo caso la funzione esterna ha già restituito il suo risultato, e quindi il senso comune sembrerebbe indicare che le sue variabili locali non siano più disponibili. Ma esse esistono ancora — altrimenti le funzioni "adder" non sarebbero capaci di lavorare. Quello che c'è di più è che ci sono due "copie" differenti delle variabili locali di makeAdder — una nella quale a è 5 e una nella quale a è 20. Così il risultato di quelle chiamate di funzione è il seguente:

+ +
x(6) // returns 11
+y(7) // returns 27
+
+ +

Ecco cosa sta effettivamente avvenendo. Quando JavaScript esegue una funzione, viene creato un oggetto con il proprio ambito di visibilità ('scope object') per trattenere le variabili locali di quella funzione. Esso è inizializzato con tutte le variabili passate in ingresso alla funzione come parametri. Ciò è simile all'oggetto globale in cui si trovano tutte le variabili globali e le funzioni, ma con una paio di differenze importanti: primo, un nuovo 'scope object' etichettato è creato ogni volta che una funzione inizia l'esecuzione, e secondo, a differenza dell'oggetto globale (che nei bowser è accessibile come 'window') non si può accedere direttamente a questi 'scope object' dal tuo codice JavaScript. Ad esempio non c'è nessun meccanismo per iterare sulle proprietà dello 'scope object' corrente.

+ +

Quindi, quando makeAdder è chiamato viene creato un oggetto scope con una proprietà: a, che è l'argomento passato alla funzione makeAdder . A questo punto makeAdder restituisce quindi una funzione appena creata. Normalmente il raccoglitore di rifiuti  di JavaScript eliminerebbe l'oggetto scope creato per makeAdder , ma la funzione restituita mantiene un riferimento a tale oggetto scope. Di conseguenza l'oggetto scope non verrà eliminato finchè non ci saranno più riferimenti all'oggetto che la funzione makeAdder restituisce.

+ +

Gli oggetti scope formano una catena chiamata 'scope chain', simile alla catena di prototipi, 'prototype chain', del sistema a oggetti di JavaScript.

+ +

Una closure è la combinazione di una funzione e dell'oggetto scope in cui è stata creata.

+ +

Le closures ti consentono di salvare lo stato e in quanto tali, possono spesso essere utilizzate al posto degli oggetti. Puoi trovare alcune eccellenti introduzioni alle closures (in lingua inglese).

+ +

Memory leaks

+ +
 Uno sfortunato effetto collaterale delle chiusure è il rendere facile perdere memoria
+ su Internet Explorer. JavaScript alloca gli oggetti nella memoria al momento della loro
+ creazione e tale memoria viene recuperata dal browser quando non rimangono riferimenti a un
+ oggetto.
+ Gli oggetti forniti dall'host vengono gestiti da quell'ambiente.
+
+ Gli host del browser devono gestire un gran numero di oggetti che rappresentano
+ la pagina HTML presentata: gli oggetti del DOM. Spetta al browser gestire l'assegnazione e
+ il recupero di questi.
+
+ Internet Explorer utilizza il proprio schema di raccolta dei rifiuti per questo,
+ separato dal meccanismo utilizzato da JavaScript.
+ È l'interazione tra i due che può causare perdite di memoria.
+
+Una perdita di memoria in IE si verifica ogni volta che viene formato un riferimento circolare
+tra un oggetto JavaScript e un oggetto nativo. Considera quanto segue:
+ +
function leakMemory() {
+    var el = document.getElementById('el');
+    var o = { 'el': el };
+    el.o = o;
+}
+
+ +

Il riferimento circolare formato sopra crea una perdita di memoria;

+ +

IE non libererà la memoria utilizzata da el fino al completo riavvio del browser. Il caso di cui sopra rischia di passare inosservato; le perdite di memoria diventano un problema reale solo nelle applicazioni a esecuzione prolungata o nelle applicazioni che perdono grandi quantità di memoria a causa di grandi strutture di dati o schemi di perdite all'interno dei loop. Le perdite sono raramente così ovvie: spesso la struttura dei dati trapelati può avere molti livelli di riferimenti, oscurando il riferimento circolare. Le chiusure rendono facile creare una perdita di memoria senza volerlo. Considera questo:

+ +
function addHandler() {
+    var el = document.getElementById('el');
+    el.onclick = function() {
+        this.style.backgroundColor = 'red';
+    }
+}
+
+ +

Il codice precedente imposta l'elemento in modo che diventi rosso quando viene cliccato. Crea anche una perdita di memoria. Perché? Perché il riferimento a el è inavvertitamente catturato nella chiusura creata per la funzione interna anonima. Questo crea un riferimento circolare tra un oggetto JavaScript (la funzione) e un oggetto nativo (el).

+ +
needsTechnicalReview();
+
+ +

Esistono numerose soluzioni per questo problema. Il più semplice è non usare la variabile el:

+ +
function addHandler(){
+    document.getElementById('el').onclick = function(){
+        this.style.backgroundColor = 'red';
+    }
+}
+
+ +

Sorprendentemente, un trucco per rompere i riferimenti circolari introdotti da una chiusura è aggiungere un'altra chiusura:

+ +
function addHandler() {
+    var clickHandler = function() {
+        this.style.backgroundColor = 'red';
+    };
+    (function() {
+        var el = document.getElementById('el');
+        el.onclick = clickHandler;
+    })();
+}
+
+ +

La funzione interna viene eseguita immediatamente, e nasconde il suo contenuto dalla chiusura creata con clickHandler. Un altro buon trucco per evitare le chiusure è rompere i riferimenti circolari durante l'evento window.onunload. Molte librerie di eventi lo faranno per te. Nota che così facendo si disabilita bfcache in Firefox 1.5, quindi non dovresti registrare un listener di scaricamento in Firefox, a meno che tu non abbia altri motivi per farlo.

+ +
+

Original Document Information

+ + +
diff --git a/files/it/web/javascript/about_javascript/index.html b/files/it/web/javascript/about_javascript/index.html new file mode 100644 index 0000000000..c850023b92 --- /dev/null +++ b/files/it/web/javascript/about_javascript/index.html @@ -0,0 +1,57 @@ +--- +title: Cos'è JavaScript +slug: Web/JavaScript/Cosè_JavaScript +translation_of: Web/JavaScript/About_JavaScript +--- +
{{JsSidebar}}
+ +

Cos'è JavaScript?

+ +

JavaScript® (spesso abbreviato con JS) è un linguaggio di programmazione, interpretato, orientato agli oggetti  con  first-class functions,  ed è meglio conosciuto come linguaggio di scripting client-side per pagine web, nonostante questo è anche utilizzato in molte applicazioninon solamente basate sul web. Il linguaggio è prototype-based,  è  dinamico, imperativo, e il offre uno stile di programmazione funzionale.

+ +

JavaScript viene eseguito direttamente lato "client-side" della pagina web e può essere utilizzato per dare un design e stabilire il comportamento delle pagine web quando viene scatenato una particolare evento da parte dell'utente. JavaScript è semplice da apprendere e nello stesso tempo rappresenta un linguaggio che permette un controllo quasi totale sulla pagina web.

+ +

Contrariamente alla concezione popolare, JavaScript non è "Java Interpretato". JavaScript è un linguaggio di scripting dinamico che supporta la costruzione degli oggetti basata su prototype. La sintassi base è intenzionalmente basata su entrambi i maggiori e più conosciuti linguaggi, C++ e Java e questo ha permesso la riduzione di nuovi concetti per lo studio del linguaggio. Costrutti del linguaggio come if, cicli for e  while, switch e blocchi try ... catch hanno il medesimo significato in questi linguaggi.

+ +

JavaScript permette di programmare sia in modo procedurale sia in orientato agli oggetti. Gli oggetti vengono creati a livello di programmazione in JavaScript, allegando metodi e proprietà agli oggetti altrimenti vuoti in fase di esecuzione, in contrasto con le definizioni di classe sintattiche comuni linguaggi compilati come C ++ e Java. Una volta che un oggetto è stato costruito può essere utilizzato come modello (o prototipo) per creare oggetti simili.

+ +

JavaScript permette la costruzione a runtime di oggetti, elenchi di parametri, funzioni come variabili, pemette la creazione di script dinamici (tramite eval), permette di esaminare a runtime tipo e proprietà di un oggetto (tramite for ... in), e il recupero del codice sorgente ( i programmi JavaScript possono decompilare parti di funzione e mostrarne il codice sorgente all'interno del codice sorgente stesso).

+ +

Per una più esaustiva trattazione del linguaggio JavaScript consulta il seguente link JavaScript resources.

+ +

Quali implementazioni del linguaggio JavaScript sono disponibili?

+ +

Il progetto Mozilla fornisce due implementazioni JavaScript. Il primo JavaScript è stato creato da Brendan Eich a Netscape, e da allora è stato aggiornato per conformarsi alle ECMA-262 Edition 5 e versioni successive. Questo motore, nome in codice SpiderMonkey, è implementato in C / C ++. Il motore di Rhino, creati principalmente da Norris Boyd (anche lui a Netscape) è una implementazione JavaScript scritto in Java. Come SpiderMonkey, Rhino è ECMA-262 Edition 5 compatibile.

+ +

Diverse ed importanti ottimizzazioni sono state aggiunte, come TraceMonkey (Firefox 3.5), JägerMonkey (Firefox 4) e IonMonkey al motore SpiderMonkey JavaScript nel corso del tempo. Il lavoro è sempre in corso per migliorare le prestazioni di esecuzione di JavaScript.

+ +

Oltre alle implementazioni di cui sopra, ci sono molti altri popolari motori JavaScript, quali: -

+ + + +

Ognuno dei motori JavaScript di Mozilla espone una API pubblica per gli sviluppatori e questa viene utilizzata per integrare JavaScript nella loro software. Di gran lunga, l'ambiente host più comune per JavaScript e lo stesso browser web. I browser Web utilizzano in genere l'API pubblica di JavaScript per la gestione e la visualizzazione della struttura DOM delle pagine web.

+ +

Un'altra applicazione comune  per cui possiamo utilizzare JavaScript è come linguaggio di scripting lato server. Un server web JavaScript esporrebbe oggetti  che rappresentano una richiesta HTTP e oggetti di risposta, che possono successivamente essere manipolati da un programma JavaScript per generare dinamicamente pagine web. Node.js è un esempio popolare di questo.

+ +

Risorse JavaScript

+ +
+
SpiderMonkey
+
Informazioni specifiche riguardanti l'implementazione del motore scritto in C / C ++ (aka SpiderMonkey), compreso il modo di incorporare nelle applicazioni.
+
+ +
+
Rhino
+
Informazioni specifiche riguardanti l'implementazione del motore scritto in Java (aka Rhino).
+
Risorse sul linguaggio
+
Informazioni sugli standard del linguaggio JavaScript.
+
Re-Introduzione a JavaScript
+
Guida JavaScript e JavaScript Reference.
+
+ +

JavaScript® è un marchio registrato di Oracle negli U.S. e in altri paesi.

diff --git a/files/it/web/javascript/chiusure/index.html b/files/it/web/javascript/chiusure/index.html deleted file mode 100644 index deee56e54b..0000000000 --- a/files/it/web/javascript/chiusure/index.html +++ /dev/null @@ -1,345 +0,0 @@ ---- -title: Chiusure -slug: Web/JavaScript/Chiusure -translation_of: Web/JavaScript/Closures ---- -
{{jsSidebar("Intermediate")}}
- -
- -

Una closure è la combinazione di una funzione e dello stato nella quale è stata creata (ambito lessicale). In altre parole, una closure consente a una funzione interna di accedere allo scope della funzione che la racchiude. In Javascript le closure sono create ogni volta che una funzione viene creata, al momento della creazione della funzione stessa.

- -

Lexical scoping

- -

Considerate la seguente:

- -
-
function init() {
-  var name = "Mozilla"; // name è una variabile locale creata da init
-  function displayName() { // displayName() è una funzione interna, una chiusura
-    alert(name); // utilizza la variabile dichiarata nella funzione padre
-  }
-  displayName();
-}
-init();
-
- -

init() crea una variabile locale name e poi una funzione chiamata displayName(). displayName() è una funzione interna che è definita dentro init() ed è disponibile solo all'interno del corpo di quella funzione. displayName() non ha proprie variabili locali. Tuttavia, poiché le funzioni interne hanno accesso alle variabili di quelle esterne, displayName() può accedere alla variabile name dichiarata nella funzione genitore, init() Tuttavia verrebbero usate le variabili locali in displayName(), se esistessero.

- -

{{JSFiddleEmbed("https://jsfiddle.net/78dg25ax/", "js,result", 200)}}

- -

Esegui il codice e verifica che funziona. Questo è un esempio di lexical scoping: in JavaScript, la visibilità (scope) di una variabile è definita dalla sua posizione all'interno del codice sorgente (si evince dal codice stesso [lexically]) e le funzioni innestate hanno accesso a variabili dichiarate nella funzione esterna (outer scope).

- -

Closure

- -

Considerate ora l'esempio seguente:

- -
function makeFunc() {
-  var name = "Mozilla";
-  function displayName() {
-    alert(name);
-  }
-  return displayName;
-}
-
-var myFunc = makeFunc();
-myFunc();
-
- -

L'esecuzione di questo codice ha esattamente lo stesso effetto dell'esempio precedente della funzione init():  la stringa "Mozilla" verrà visualizzata in una casella di avviso JavaScript. La cosa differente ed interessante, è che la funzione interna displayName() viene restituita dalla funzione esterna prima di essere eseguita.

- -

A un primo sguardo sembrerebbe controintuitivo che il codice funzioni ancora. In alcuni linguaggi di programmazione le variabili locali interne a una funzione esistono solo per la durata dell'esecuzione della funzione stessa. Una volta che makeFunc() ha terminato la propria esecuzione, ci si potrebbe aspettare che la variabile name non sia più accessibile. Tuttavia, poiché il codice funziona ancora, è ovvio che in JavaScript non è il caso.

- -

La ragione è che le funzioni in JavaScript formano closures. Una closure è la combinazione di una funzione e dell'ambito lessicale in cui questa funzione è stata dichiarata. In questo caso, myFunc è un riferimento all'istanza della funzione displayName creata quando makeFunc è eseguita.

- -

La soluzione di questo rompicampo è che myFunc è diventata una closure. Una closure è uno speciale tipo di oggetto che combina due cose: una funzione e l'ambito in cui questa è stata creata. L'ambito consiste in qualsiasi variabile locale che era nel suo scope nel momento in cui la closure è stata creata. In questo caso, myFunc è una closure che incorpora sia la funzione displayName che la stringa "Mozilla", già esistente quando la closure è stata creata.

- -

Ecco un esempio leggermente più interessante — una funzione makeAdder:

- -
function makeAdder(x) {
-  return function(y) {
-    return x + y;
-  };
-}
-
-var add5 = makeAdder(5);
-var add10 = makeAdder(10);
-
-console.log(add5(2));  // 7
-console.log(add10(2)); // 12
-
- -

In questo esempio, abbiamo definito una funzione makeAdder(x) che prende un singolo argomento x e restituisce una nuova funzione. La funzione restituita prende un singolo argomento y, e restituisce la somma tra xy.

- -

In sostanza, makeAdder è una factory function — crea funzioni che possono aggiungere uno specifico valore come argomento. Nell'esempio sopra usiamo la nostra factory function per creare due nuove funzioni — una che aggiunge 5 ai suoi argomenti, e una che aggiunge 10.

- -

add5add10 sono entrambe closures. Condividono la stessa definizione del corpo della funzione, ma memorizzano diversi ambienti. Nell'ambiente di add5, x vale 5. Per quanto riguarda add10 , x vale 10.

- -

Practical closures

- -

That's the theory of closures — but are closures actually useful? Let's consider their practical implications. A closure lets you associate some data (the environment) with a function that operates on that data. This has obvious parallels to object oriented programming, where objects allow us to associate some data (the object's properties) with one or more methods.

- -

Consequently, you can use a closure anywhere that you might normally use an object with only a single method.

- -

Situations where you might want to do this are particularly common on the web. Much of the code we write in web JavaScript is event-based — we define some behavior, then attach it to an event that is triggered by the user (such as a click or a keypress). Our code is generally attached as a callback: a single function which is executed in response to the event.

- -

Here's a practical example: suppose we wish to add some buttons to a page that adjust the text size. One way of doing this is to specify the font-size of the body element in pixels, then set the size of the other elements on the page (such as headers) using the relative em unit:

- -
body {
-  font-family: Helvetica, Arial, sans-serif;
-  font-size: 12px;
-}
-
-h1 {
-  font-size: 1.5em;
-}
-
-h2 {
-  font-size: 1.2em;
-}
-
- -

Our interactive text size buttons can change the font-size property of the body element, and the adjustments will be picked up by other elements on the page thanks to the relative units.

- -

Qui c'è il codice JavaScript:

- -
function makeSizer(size) {
-  return function() {
-    document.body.style.fontSize = size + 'px';
-  };
-}
-
-var size12 = makeSizer(12);
-var size14 = makeSizer(14);
-var size16 = makeSizer(16);
-
- -

size12, size14, and size16 are now functions which will resize the body text to 12, 14, and 16 pixels, respectively. We can attach them to buttons (in this case links) as follows:

- -
document.getElementById('size-12').onclick = size12;
-document.getElementById('size-14').onclick = size14;
-document.getElementById('size-16').onclick = size16;
-
- -
<a href="#" id="size-12">12</a>
-<a href="#" id="size-14">14</a>
-<a href="#" id="size-16">16</a>
-
- -

{{JSFiddleEmbed("https://jsfiddle.net/vnkuZ/","","200")}}

- -

Emulare metodi privati con chiusure

- -

Languages such as Java provide the ability to declare methods private, meaning that they can only be called by other methods in the same class.

- -

JavaScript does not provide a native way of doing this, but it is possible to emulate private methods using closures. Private methods aren't just useful for restricting access to code: they also provide a powerful way of managing your global namespace, keeping non-essential methods from cluttering up the public interface to your code.

- -

Here's how to define some public functions that can access private functions and variables, using closures which is also known as the module pattern:

- -
var counter = (function() {
-  var privateCounter = 0;
-  function changeBy(val) {
-    privateCounter += val;
-  }
-  return {
-    increment: function() {
-      changeBy(1);
-    },
-    decrement: function() {
-      changeBy(-1);
-    },
-    value: function() {
-      return privateCounter;
-    }
-  };
-})();
-
-console.log(counter.value()); // logs 0
-counter.increment();
-counter.increment();
-console.log(counter.value()); // logs 2
-counter.decrement();
-console.log(counter.value()); // logs 1
-
- -

There's a lot going on here. In previous examples each closure has had its own environment; here we create a single environment which is shared by three functions: counter.increment, counter.decrement, and counter.value.

- -

The shared environment is created in the body of an anonymous function, which is executed as soon as it has been defined. The environment contains two private items: a variable called privateCounter and a function called changeBy. Neither of these private items can be accessed directly from outside the anonymous function. Instead, they must be accessed by the three public functions that are returned from the anonymous wrapper.

- -

Those three public functions are closures that share the same environment. Thanks to JavaScript's lexical scoping, they each have access to the privateCounter variable and changeBy function.

- -

You'll notice we're defining an anonymous function that creates a counter, and then we call it immediately and assign the result to the counter variable. We could store this function in a separate variable makeCounter and use it to create several counters.

- -
var makeCounter = function() {
-  var privateCounter = 0;
-  function changeBy(val) {
-    privateCounter += val;
-  }
-  return {
-    increment: function() {
-      changeBy(1);
-    },
-    decrement: function() {
-      changeBy(-1);
-    },
-    value: function() {
-      return privateCounter;
-    }
-  }
-};
-
-var counter1 = makeCounter();
-var counter2 = makeCounter();
-alert(counter1.value()); /* Alerts 0 */
-counter1.increment();
-counter1.increment();
-alert(counter1.value()); /* Alerts 2 */
-counter1.decrement();
-alert(counter1.value()); /* Alerts 1 */
-alert(counter2.value()); /* Alerts 0 */
-
- -

Notice how each of the two counters maintains its independence from the other. Its environment during the call of the makeCounter() function is different each time. The closure variable privateCounter contains a different instance each time.

- -

Using closures in this way provides a number of benefits that are normally associated with object oriented programming, in particular data hiding and encapsulation.

- -

Creating closures in loops: A common mistake

- -

Prior to the introduction of the let keyword in ECMAScript 6, a common problem with closures occurred when they were created inside a loop. Consider the following example:

- -
<p id="help">Helpful notes will appear here</p>
-<p>E-mail: <input type="text" id="email" name="email"></p>
-<p>Name: <input type="text" id="name" name="name"></p>
-<p>Age: <input type="text" id="age" name="age"></p>
-
- -
function showHelp(help) {
-  document.getElementById('help').innerHTML = help;
-}
-
-function setupHelp() {
-  var helpText = [
-      {'id': 'email', 'help': 'Your e-mail address'},
-      {'id': 'name', 'help': 'Your full name'},
-      {'id': 'age', 'help': 'Your age (you must be over 16)'}
-    ];
-
-  for (var i = 0; i < helpText.length; i++) {
-    var item = helpText[i];
-    document.getElementById(item.id).onfocus = function() {
-      showHelp(item.help);
-    }
-  }
-}
-
-setupHelp();
-
- -

{{JSFiddleEmbed("https://jsfiddle.net/v7gjv/", "", 200)}}

- -

The helpText array defines three helpful hints, each associated with the ID of an input field in the document. The loop cycles through these definitions, hooking up an onfocus event to each one that shows the associated help method.

- -

If you try this code out, you'll see that it doesn't work as expected. No matter what field you focus on, the message about your age will be displayed.

- -

The reason for this is that the functions assigned to onfocus are closures; they consist of the function definition and the captured environment from the setupHelp function's scope. Three closures have been created, but each one shares the same single environment. By the time the onfocus callbacks are executed, the loop has run its course and the item variable (shared by all three closures) has been left pointing to the last entry in the helpText list.

- -

One solution in this case is to use more closures: in particular, to use a function factory as described earlier on:

- -
function showHelp(help) {
-  document.getElementById('help').innerHTML = help;
-}
-
-function makeHelpCallback(help) {
-  return function() {
-    showHelp(help);
-  };
-}
-
-function setupHelp() {
-  var helpText = [
-      {'id': 'email', 'help': 'Your e-mail address'},
-      {'id': 'name', 'help': 'Your full name'},
-      {'id': 'age', 'help': 'Your age (you must be over 16)'}
-    ];
-
-  for (var i = 0; i < helpText.length; i++) {
-    var item = helpText[i];
-    document.getElementById(item.id).onfocus = makeHelpCallback(item.help);
-  }
-}
-
-setupHelp();
-
- -

{{JSFiddleEmbed("https://jsfiddle.net/v7gjv/1/", "", 300)}}

- -

This works as expected. Rather than the callbacks all sharing a single environment, the makeHelpCallback function creates a new environment for each one in which help refers to the corresponding string from the helpText array.

- -

Performance considerations

- -

It is unwise to unnecessarily create functions within other functions if closures are not needed for a particular task, as it will negatively affect script performance both in terms of processing speed and memory consumption.

- -

For instance, when creating a new object/class, methods should normally be associated to the object's prototype rather than defined into the object constructor. The reason is that whenever the constructor is called, the methods would get reassigned (that is, for every object creation).

- -

Consider the following impractical but demonstrative case:

- -
function MyObject(name, message) {
-  this.name = name.toString();
-  this.message = message.toString();
-  this.getName = function() {
-    return this.name;
-  };
-
-  this.getMessage = function() {
-    return this.message;
-  };
-}
-
- -

The previous code does not take advantage of the benefits of closures and thus could instead be formulated:

- -
function MyObject(name, message) {
-  this.name = name.toString();
-  this.message = message.toString();
-}
-MyObject.prototype = {
-  getName: function() {
-    return this.name;
-  },
-  getMessage: function() {
-    return this.message;
-  }
-};
-
- -

However, redefining the prototype is not recommended, so the following example is even better because it appends to the existing prototype:

- -
function MyObject(name, message) {
-  this.name = name.toString();
-  this.message = message.toString();
-}
-MyObject.prototype.getName = function() {
-  return this.name;
-};
-MyObject.prototype.getMessage = function() {
-  return this.message;
-};
-
- -

Il codice sopra può essere riscritto meglio in un modo più pulito, con lo stesso risultato:

- -
function MyObject(name, message) {
-    this.name = name.toString();
-    this.message = message.toString();
-}
-(function() {
-    this.getName = function() {
-        return this.name;
-    };
-    this.getMessage = function() {
-        return this.message;
-    };
-}).call(MyObject.prototype);
-
- -

In the two previous examples, the inherited prototype can be shared by all objects and the method definitions need not occur at every object creation. See Details of the Object Model for more details.

diff --git a/files/it/web/javascript/closures/index.html b/files/it/web/javascript/closures/index.html new file mode 100644 index 0000000000..deee56e54b --- /dev/null +++ b/files/it/web/javascript/closures/index.html @@ -0,0 +1,345 @@ +--- +title: Chiusure +slug: Web/JavaScript/Chiusure +translation_of: Web/JavaScript/Closures +--- +
{{jsSidebar("Intermediate")}}
+ +
+ +

Una closure è la combinazione di una funzione e dello stato nella quale è stata creata (ambito lessicale). In altre parole, una closure consente a una funzione interna di accedere allo scope della funzione che la racchiude. In Javascript le closure sono create ogni volta che una funzione viene creata, al momento della creazione della funzione stessa.

+ +

Lexical scoping

+ +

Considerate la seguente:

+ +
+
function init() {
+  var name = "Mozilla"; // name è una variabile locale creata da init
+  function displayName() { // displayName() è una funzione interna, una chiusura
+    alert(name); // utilizza la variabile dichiarata nella funzione padre
+  }
+  displayName();
+}
+init();
+
+ +

init() crea una variabile locale name e poi una funzione chiamata displayName(). displayName() è una funzione interna che è definita dentro init() ed è disponibile solo all'interno del corpo di quella funzione. displayName() non ha proprie variabili locali. Tuttavia, poiché le funzioni interne hanno accesso alle variabili di quelle esterne, displayName() può accedere alla variabile name dichiarata nella funzione genitore, init() Tuttavia verrebbero usate le variabili locali in displayName(), se esistessero.

+ +

{{JSFiddleEmbed("https://jsfiddle.net/78dg25ax/", "js,result", 200)}}

+ +

Esegui il codice e verifica che funziona. Questo è un esempio di lexical scoping: in JavaScript, la visibilità (scope) di una variabile è definita dalla sua posizione all'interno del codice sorgente (si evince dal codice stesso [lexically]) e le funzioni innestate hanno accesso a variabili dichiarate nella funzione esterna (outer scope).

+ +

Closure

+ +

Considerate ora l'esempio seguente:

+ +
function makeFunc() {
+  var name = "Mozilla";
+  function displayName() {
+    alert(name);
+  }
+  return displayName;
+}
+
+var myFunc = makeFunc();
+myFunc();
+
+ +

L'esecuzione di questo codice ha esattamente lo stesso effetto dell'esempio precedente della funzione init():  la stringa "Mozilla" verrà visualizzata in una casella di avviso JavaScript. La cosa differente ed interessante, è che la funzione interna displayName() viene restituita dalla funzione esterna prima di essere eseguita.

+ +

A un primo sguardo sembrerebbe controintuitivo che il codice funzioni ancora. In alcuni linguaggi di programmazione le variabili locali interne a una funzione esistono solo per la durata dell'esecuzione della funzione stessa. Una volta che makeFunc() ha terminato la propria esecuzione, ci si potrebbe aspettare che la variabile name non sia più accessibile. Tuttavia, poiché il codice funziona ancora, è ovvio che in JavaScript non è il caso.

+ +

La ragione è che le funzioni in JavaScript formano closures. Una closure è la combinazione di una funzione e dell'ambito lessicale in cui questa funzione è stata dichiarata. In questo caso, myFunc è un riferimento all'istanza della funzione displayName creata quando makeFunc è eseguita.

+ +

La soluzione di questo rompicampo è che myFunc è diventata una closure. Una closure è uno speciale tipo di oggetto che combina due cose: una funzione e l'ambito in cui questa è stata creata. L'ambito consiste in qualsiasi variabile locale che era nel suo scope nel momento in cui la closure è stata creata. In questo caso, myFunc è una closure che incorpora sia la funzione displayName che la stringa "Mozilla", già esistente quando la closure è stata creata.

+ +

Ecco un esempio leggermente più interessante — una funzione makeAdder:

+ +
function makeAdder(x) {
+  return function(y) {
+    return x + y;
+  };
+}
+
+var add5 = makeAdder(5);
+var add10 = makeAdder(10);
+
+console.log(add5(2));  // 7
+console.log(add10(2)); // 12
+
+ +

In questo esempio, abbiamo definito una funzione makeAdder(x) che prende un singolo argomento x e restituisce una nuova funzione. La funzione restituita prende un singolo argomento y, e restituisce la somma tra xy.

+ +

In sostanza, makeAdder è una factory function — crea funzioni che possono aggiungere uno specifico valore come argomento. Nell'esempio sopra usiamo la nostra factory function per creare due nuove funzioni — una che aggiunge 5 ai suoi argomenti, e una che aggiunge 10.

+ +

add5add10 sono entrambe closures. Condividono la stessa definizione del corpo della funzione, ma memorizzano diversi ambienti. Nell'ambiente di add5, x vale 5. Per quanto riguarda add10 , x vale 10.

+ +

Practical closures

+ +

That's the theory of closures — but are closures actually useful? Let's consider their practical implications. A closure lets you associate some data (the environment) with a function that operates on that data. This has obvious parallels to object oriented programming, where objects allow us to associate some data (the object's properties) with one or more methods.

+ +

Consequently, you can use a closure anywhere that you might normally use an object with only a single method.

+ +

Situations where you might want to do this are particularly common on the web. Much of the code we write in web JavaScript is event-based — we define some behavior, then attach it to an event that is triggered by the user (such as a click or a keypress). Our code is generally attached as a callback: a single function which is executed in response to the event.

+ +

Here's a practical example: suppose we wish to add some buttons to a page that adjust the text size. One way of doing this is to specify the font-size of the body element in pixels, then set the size of the other elements on the page (such as headers) using the relative em unit:

+ +
body {
+  font-family: Helvetica, Arial, sans-serif;
+  font-size: 12px;
+}
+
+h1 {
+  font-size: 1.5em;
+}
+
+h2 {
+  font-size: 1.2em;
+}
+
+ +

Our interactive text size buttons can change the font-size property of the body element, and the adjustments will be picked up by other elements on the page thanks to the relative units.

+ +

Qui c'è il codice JavaScript:

+ +
function makeSizer(size) {
+  return function() {
+    document.body.style.fontSize = size + 'px';
+  };
+}
+
+var size12 = makeSizer(12);
+var size14 = makeSizer(14);
+var size16 = makeSizer(16);
+
+ +

size12, size14, and size16 are now functions which will resize the body text to 12, 14, and 16 pixels, respectively. We can attach them to buttons (in this case links) as follows:

+ +
document.getElementById('size-12').onclick = size12;
+document.getElementById('size-14').onclick = size14;
+document.getElementById('size-16').onclick = size16;
+
+ +
<a href="#" id="size-12">12</a>
+<a href="#" id="size-14">14</a>
+<a href="#" id="size-16">16</a>
+
+ +

{{JSFiddleEmbed("https://jsfiddle.net/vnkuZ/","","200")}}

+ +

Emulare metodi privati con chiusure

+ +

Languages such as Java provide the ability to declare methods private, meaning that they can only be called by other methods in the same class.

+ +

JavaScript does not provide a native way of doing this, but it is possible to emulate private methods using closures. Private methods aren't just useful for restricting access to code: they also provide a powerful way of managing your global namespace, keeping non-essential methods from cluttering up the public interface to your code.

+ +

Here's how to define some public functions that can access private functions and variables, using closures which is also known as the module pattern:

+ +
var counter = (function() {
+  var privateCounter = 0;
+  function changeBy(val) {
+    privateCounter += val;
+  }
+  return {
+    increment: function() {
+      changeBy(1);
+    },
+    decrement: function() {
+      changeBy(-1);
+    },
+    value: function() {
+      return privateCounter;
+    }
+  };
+})();
+
+console.log(counter.value()); // logs 0
+counter.increment();
+counter.increment();
+console.log(counter.value()); // logs 2
+counter.decrement();
+console.log(counter.value()); // logs 1
+
+ +

There's a lot going on here. In previous examples each closure has had its own environment; here we create a single environment which is shared by three functions: counter.increment, counter.decrement, and counter.value.

+ +

The shared environment is created in the body of an anonymous function, which is executed as soon as it has been defined. The environment contains two private items: a variable called privateCounter and a function called changeBy. Neither of these private items can be accessed directly from outside the anonymous function. Instead, they must be accessed by the three public functions that are returned from the anonymous wrapper.

+ +

Those three public functions are closures that share the same environment. Thanks to JavaScript's lexical scoping, they each have access to the privateCounter variable and changeBy function.

+ +

You'll notice we're defining an anonymous function that creates a counter, and then we call it immediately and assign the result to the counter variable. We could store this function in a separate variable makeCounter and use it to create several counters.

+ +
var makeCounter = function() {
+  var privateCounter = 0;
+  function changeBy(val) {
+    privateCounter += val;
+  }
+  return {
+    increment: function() {
+      changeBy(1);
+    },
+    decrement: function() {
+      changeBy(-1);
+    },
+    value: function() {
+      return privateCounter;
+    }
+  }
+};
+
+var counter1 = makeCounter();
+var counter2 = makeCounter();
+alert(counter1.value()); /* Alerts 0 */
+counter1.increment();
+counter1.increment();
+alert(counter1.value()); /* Alerts 2 */
+counter1.decrement();
+alert(counter1.value()); /* Alerts 1 */
+alert(counter2.value()); /* Alerts 0 */
+
+ +

Notice how each of the two counters maintains its independence from the other. Its environment during the call of the makeCounter() function is different each time. The closure variable privateCounter contains a different instance each time.

+ +

Using closures in this way provides a number of benefits that are normally associated with object oriented programming, in particular data hiding and encapsulation.

+ +

Creating closures in loops: A common mistake

+ +

Prior to the introduction of the let keyword in ECMAScript 6, a common problem with closures occurred when they were created inside a loop. Consider the following example:

+ +
<p id="help">Helpful notes will appear here</p>
+<p>E-mail: <input type="text" id="email" name="email"></p>
+<p>Name: <input type="text" id="name" name="name"></p>
+<p>Age: <input type="text" id="age" name="age"></p>
+
+ +
function showHelp(help) {
+  document.getElementById('help').innerHTML = help;
+}
+
+function setupHelp() {
+  var helpText = [
+      {'id': 'email', 'help': 'Your e-mail address'},
+      {'id': 'name', 'help': 'Your full name'},
+      {'id': 'age', 'help': 'Your age (you must be over 16)'}
+    ];
+
+  for (var i = 0; i < helpText.length; i++) {
+    var item = helpText[i];
+    document.getElementById(item.id).onfocus = function() {
+      showHelp(item.help);
+    }
+  }
+}
+
+setupHelp();
+
+ +

{{JSFiddleEmbed("https://jsfiddle.net/v7gjv/", "", 200)}}

+ +

The helpText array defines three helpful hints, each associated with the ID of an input field in the document. The loop cycles through these definitions, hooking up an onfocus event to each one that shows the associated help method.

+ +

If you try this code out, you'll see that it doesn't work as expected. No matter what field you focus on, the message about your age will be displayed.

+ +

The reason for this is that the functions assigned to onfocus are closures; they consist of the function definition and the captured environment from the setupHelp function's scope. Three closures have been created, but each one shares the same single environment. By the time the onfocus callbacks are executed, the loop has run its course and the item variable (shared by all three closures) has been left pointing to the last entry in the helpText list.

+ +

One solution in this case is to use more closures: in particular, to use a function factory as described earlier on:

+ +
function showHelp(help) {
+  document.getElementById('help').innerHTML = help;
+}
+
+function makeHelpCallback(help) {
+  return function() {
+    showHelp(help);
+  };
+}
+
+function setupHelp() {
+  var helpText = [
+      {'id': 'email', 'help': 'Your e-mail address'},
+      {'id': 'name', 'help': 'Your full name'},
+      {'id': 'age', 'help': 'Your age (you must be over 16)'}
+    ];
+
+  for (var i = 0; i < helpText.length; i++) {
+    var item = helpText[i];
+    document.getElementById(item.id).onfocus = makeHelpCallback(item.help);
+  }
+}
+
+setupHelp();
+
+ +

{{JSFiddleEmbed("https://jsfiddle.net/v7gjv/1/", "", 300)}}

+ +

This works as expected. Rather than the callbacks all sharing a single environment, the makeHelpCallback function creates a new environment for each one in which help refers to the corresponding string from the helpText array.

+ +

Performance considerations

+ +

It is unwise to unnecessarily create functions within other functions if closures are not needed for a particular task, as it will negatively affect script performance both in terms of processing speed and memory consumption.

+ +

For instance, when creating a new object/class, methods should normally be associated to the object's prototype rather than defined into the object constructor. The reason is that whenever the constructor is called, the methods would get reassigned (that is, for every object creation).

+ +

Consider the following impractical but demonstrative case:

+ +
function MyObject(name, message) {
+  this.name = name.toString();
+  this.message = message.toString();
+  this.getName = function() {
+    return this.name;
+  };
+
+  this.getMessage = function() {
+    return this.message;
+  };
+}
+
+ +

The previous code does not take advantage of the benefits of closures and thus could instead be formulated:

+ +
function MyObject(name, message) {
+  this.name = name.toString();
+  this.message = message.toString();
+}
+MyObject.prototype = {
+  getName: function() {
+    return this.name;
+  },
+  getMessage: function() {
+    return this.message;
+  }
+};
+
+ +

However, redefining the prototype is not recommended, so the following example is even better because it appends to the existing prototype:

+ +
function MyObject(name, message) {
+  this.name = name.toString();
+  this.message = message.toString();
+}
+MyObject.prototype.getName = function() {
+  return this.name;
+};
+MyObject.prototype.getMessage = function() {
+  return this.message;
+};
+
+ +

Il codice sopra può essere riscritto meglio in un modo più pulito, con lo stesso risultato:

+ +
function MyObject(name, message) {
+    this.name = name.toString();
+    this.message = message.toString();
+}
+(function() {
+    this.getName = function() {
+        return this.name;
+    };
+    this.getMessage = function() {
+        return this.message;
+    };
+}).call(MyObject.prototype);
+
+ +

In the two previous examples, the inherited prototype can be shared by all objects and the method definitions need not occur at every object creation. See Details of the Object Model for more details.

diff --git "a/files/it/web/javascript/cos\303\250_javascript/index.html" "b/files/it/web/javascript/cos\303\250_javascript/index.html" deleted file mode 100644 index c850023b92..0000000000 --- "a/files/it/web/javascript/cos\303\250_javascript/index.html" +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: Cos'è JavaScript -slug: Web/JavaScript/Cosè_JavaScript -translation_of: Web/JavaScript/About_JavaScript ---- -
{{JsSidebar}}
- -

Cos'è JavaScript?

- -

JavaScript® (spesso abbreviato con JS) è un linguaggio di programmazione, interpretato, orientato agli oggetti  con  first-class functions,  ed è meglio conosciuto come linguaggio di scripting client-side per pagine web, nonostante questo è anche utilizzato in molte applicazioninon solamente basate sul web. Il linguaggio è prototype-based,  è  dinamico, imperativo, e il offre uno stile di programmazione funzionale.

- -

JavaScript viene eseguito direttamente lato "client-side" della pagina web e può essere utilizzato per dare un design e stabilire il comportamento delle pagine web quando viene scatenato una particolare evento da parte dell'utente. JavaScript è semplice da apprendere e nello stesso tempo rappresenta un linguaggio che permette un controllo quasi totale sulla pagina web.

- -

Contrariamente alla concezione popolare, JavaScript non è "Java Interpretato". JavaScript è un linguaggio di scripting dinamico che supporta la costruzione degli oggetti basata su prototype. La sintassi base è intenzionalmente basata su entrambi i maggiori e più conosciuti linguaggi, C++ e Java e questo ha permesso la riduzione di nuovi concetti per lo studio del linguaggio. Costrutti del linguaggio come if, cicli for e  while, switch e blocchi try ... catch hanno il medesimo significato in questi linguaggi.

- -

JavaScript permette di programmare sia in modo procedurale sia in orientato agli oggetti. Gli oggetti vengono creati a livello di programmazione in JavaScript, allegando metodi e proprietà agli oggetti altrimenti vuoti in fase di esecuzione, in contrasto con le definizioni di classe sintattiche comuni linguaggi compilati come C ++ e Java. Una volta che un oggetto è stato costruito può essere utilizzato come modello (o prototipo) per creare oggetti simili.

- -

JavaScript permette la costruzione a runtime di oggetti, elenchi di parametri, funzioni come variabili, pemette la creazione di script dinamici (tramite eval), permette di esaminare a runtime tipo e proprietà di un oggetto (tramite for ... in), e il recupero del codice sorgente ( i programmi JavaScript possono decompilare parti di funzione e mostrarne il codice sorgente all'interno del codice sorgente stesso).

- -

Per una più esaustiva trattazione del linguaggio JavaScript consulta il seguente link JavaScript resources.

- -

Quali implementazioni del linguaggio JavaScript sono disponibili?

- -

Il progetto Mozilla fornisce due implementazioni JavaScript. Il primo JavaScript è stato creato da Brendan Eich a Netscape, e da allora è stato aggiornato per conformarsi alle ECMA-262 Edition 5 e versioni successive. Questo motore, nome in codice SpiderMonkey, è implementato in C / C ++. Il motore di Rhino, creati principalmente da Norris Boyd (anche lui a Netscape) è una implementazione JavaScript scritto in Java. Come SpiderMonkey, Rhino è ECMA-262 Edition 5 compatibile.

- -

Diverse ed importanti ottimizzazioni sono state aggiunte, come TraceMonkey (Firefox 3.5), JägerMonkey (Firefox 4) e IonMonkey al motore SpiderMonkey JavaScript nel corso del tempo. Il lavoro è sempre in corso per migliorare le prestazioni di esecuzione di JavaScript.

- -

Oltre alle implementazioni di cui sopra, ci sono molti altri popolari motori JavaScript, quali: -

- - - -

Ognuno dei motori JavaScript di Mozilla espone una API pubblica per gli sviluppatori e questa viene utilizzata per integrare JavaScript nella loro software. Di gran lunga, l'ambiente host più comune per JavaScript e lo stesso browser web. I browser Web utilizzano in genere l'API pubblica di JavaScript per la gestione e la visualizzazione della struttura DOM delle pagine web.

- -

Un'altra applicazione comune  per cui possiamo utilizzare JavaScript è come linguaggio di scripting lato server. Un server web JavaScript esporrebbe oggetti  che rappresentano una richiesta HTTP e oggetti di risposta, che possono successivamente essere manipolati da un programma JavaScript per generare dinamicamente pagine web. Node.js è un esempio popolare di questo.

- -

Risorse JavaScript

- -
-
SpiderMonkey
-
Informazioni specifiche riguardanti l'implementazione del motore scritto in C / C ++ (aka SpiderMonkey), compreso il modo di incorporare nelle applicazioni.
-
- -
-
Rhino
-
Informazioni specifiche riguardanti l'implementazione del motore scritto in Java (aka Rhino).
-
Risorse sul linguaggio
-
Informazioni sugli standard del linguaggio JavaScript.
-
Re-Introduzione a JavaScript
-
Guida JavaScript e JavaScript Reference.
-
- -

JavaScript® è un marchio registrato di Oracle negli U.S. e in altri paesi.

diff --git a/files/it/web/javascript/gestione_della_memoria/index.html b/files/it/web/javascript/gestione_della_memoria/index.html deleted file mode 100644 index d1cd6c4dca..0000000000 --- a/files/it/web/javascript/gestione_della_memoria/index.html +++ /dev/null @@ -1,197 +0,0 @@ ---- -title: Gestione della memoria -slug: Web/JavaScript/Gestione_della_Memoria -translation_of: Web/JavaScript/Memory_Management ---- -
{{JsSidebar("Advanced")}}
- -

Introduzione

- -

Alcuni linguaggi di programmazione, come ad esempio C e C++, possiedono funzioni per la gestione della memoria a basso livello come malloc() e free(); in JavaScript l'allocazione e la de-allocazione della memoria (oggetti, stringhe, ecc.) avviene "automaticamente" grazie alla presenza del Garbage Collection. Il termine "automaticamente" è spesso fonte di confusione tra i programmatori JavaScript (e di altri linguaggi ad alto livello) poichè da l'impressione che si possa non preoccuparsi riguardo la gestione della memoria. Questo è un errore!

- -

Ciclo di vita della memoria

- -

A prescindere dal linguaggio di programmazione, il ciclo di vita della memoria è pressappoco sempre lo stesso:

- -
    -
  1. Allocazione della memoria necessaria
  2. -
  3. Utilizzo della memoria (scrittura, lettura)
  4. -
  5. Rilascio della memoria allocata quando non è più necessaria
  6. -
- -

I primi due punti sono espliciti in tutti i linguaggi; l'ultimo invece è esplicito nei linguaggi a basso livello, mentre il più delle volte implicito nei linguaggi ad alto livello come JavaScript.

- -

Allocazione in JavaScript

- -

Inizializzazione con valore

- -

Per evitare che il programmatore debba allocare ogni variabile utilizzata, JavaScript lo fa contestualmente alla dichiarazione:

- -
var n = 123; // alloca memoria per un numero
-var s = "qwerty"; // alloca memoria per una stringa
-
-var o = {
-  a: 1,
-  b: null
-}; // alloca memoria per un oggetto e i valori contenuti
-
-// (come un oggetto) alloca memoria per l'array e i valori contenuti
-var a = [1, null, "abra"];
-
-function f(a){
-  return a + 2;
-} // alloca una funzione (cioè un oggetto invocabile)
-
-// istruzioni più complesse anche allocano un oggetto
-someElement.addEventListener('click', function(){
-  someElement.style.backgroundColor = 'blue';
-}, false);
-
- -

Allocazione via chiamata di funzione

- -

La chiamata di alcune funzioni risultano nell'allocazione di un oggetto, come nel seguente esempio:

- -
var d = new Date();
-// alloca un DOM element
-var e = document.createElement('div');
-
- -

Alcuni metodi allocano nuovi valori od oggetti:

- -
var s = "qwerty";
-var s2 = s.substr(0, 3); // s2 è una nuova stringa
-// Dato che le stringhe sono valori immutabili,
-// JavaScript può decidere di non allocare memoria per una nuova stringa,
-// ma semplicemente di salvare il range [0, 3].
-
-var a = ["ouais ouais", "nan nan"];
-var a2 = ["generation", "nan nan"];
-var a3 = a.concat(a2);
-// Un nuovo array di 4 elementi, la concatenazione degli elementi di a e a2
-
- -

Utilizzo dei valori

- -

Usare i valori in sostanza significa accedere alla memoria allocata. Questo può essere fatto leggendo o scrivendo il valore di una variabile, di una proprietà di un oggetto, o anche semplicemente passando un argomento a una funzione.

- -

Rilascio della memoria quando non più necessaria

- -

La maggior parte dei problemi riguardo la gestione della memoria arrivano in questa fase; L'impresa più difficile è determinare quando "la memoria allocata non è più necessaria". Ciò si traduce per il programmatore in individuare dove, nel codice, questo pezzo di memoria non risulta più necessario, e quindi liberarlo.

- -

I linguaggi ad alto livello hanno una funzionalità chiamata "Garbage Collector" il cui compito è di seguire l'allocazione e l'uso della memoria così da determinare quando una porzione della memoria allocata non è più necessaria e liberarla automaticamente. Questo processo è un approssimazione dato che il problema generico di conoscere se una porzione di memoria serve o no è irrisolvibile (non può essere risolto da un algoritmo).

- -

Garbage Collection

- -

Partendo dal presupposto che il generico problema di sapere dove una determinata porzione di memoria "non serve più" è irrisolvibile, come conseguenza, l'implementazione dei garbege collection sono una restrizione della soluzione del problema generico. Questa sezione illustra le nozioni necessarie a capire il funzionamento dei principali algoritmi che implementano i garbage collection e le loro limitazioni.

- -

Referenze

- -

L'idea principale su cui si basano gli algoritmi di garbage collection sono le referenze. Nel contesto della gestione della memoria, un oggetto è referente di un altro se può accedere a quest'ultimo (sia in modo implicito che esplicito). Ad esempio, un oggetto JavaScript è referente del suo prototype (referenza implicita) e ai valori delle sue proprietà (referenza esplicita).

- -

In questo contesto, il concetto di "oggetto" si estende a qualcosa di molto più ampio rispetto al tradizionale concetto di "oggetto JavaScript" e contiene function scopes (or the global lexical scope).

- -

Reference-counting garbage collection

- -

Quello qui descritto è l'algoritmo di garbage collection più semplice. Esso riduce il problema da "quando un oggetto non serve più" a "quando un oggetto non è più referenziato da nessun altro oggetto". Un oggetto è considerato garbage collectable (letteralmente, spazzatura da raccogliere) se nessun altro oggetto ha almeno una referenza ad esso.

- -

Esempio

- -
var o = {
-  a: {
-    b:2
-  }
-};
-// Alloca 2 oggetti. Il primo è referenziato dall'altro come sua proprietà.
-// L'altro è referenziato dalla dalla virtù di essere assegnato alla variabile 'o'.
-// Ovviamente, nessuno dei due può essere cancellato per liberare memoria
-
-
-var o2 = o; // la variabile 'o2' è il secondo oggetto
-            // che referenzia lo stesso oggetto di 'o'
-o = 1;      // ora l'oggetto che originariamente era in 'o' ha un'unica referenza
-            // rappresentata dalla variabile 'o2'
-
-var oa = o2.a; // referenza alla proprietà 'a' dell'oggetto.
-               // Quest'oggetto ora ha 2 referenze: una come proprietà di 'o2'
-               // e una come variabile 'oa'
-
-o2 = "yo"; // L'oggetto che originariamente era in 'o' adesso non
-           // più alcuna referenza e può essere cancellato.
-           // Però la sua proprietà 'a' è ancora referenziata
-           // dall'oggetto 'oa', quindi non può essere ancora eliminato
-
-oa = null; // la proprietà 'a' del precedente oggetto adesso non ha
-           // alcuna referenza. Può essere cancellata.
-
- -

Limitazione: cicli di referenze

- -

Questo algotitmo ha una limitazione quando entra in un ciclo di referenze. Nell'esempio seguente sono creati due oggetti che si referenziano a vicenda, uno referenzia l'altro e viceversa, creando un ciclo di referenze (dipendenza ciclica). In questo modo ogni oggetto ha almento una referenza, l'algoritmo del reference-countig (ovvero quello che "conta" quante referenze ha un oggetto) da come risultato che nessuno dei due oggetti può essere cancellato (non sono garbage-collactable).

- -
function f(){
-  var o = {};
-  var o2 = {};
-  o.a = o2; // o referenzia o2
-  o2.a = o; // o2 referenzia o
-
-  return "qwerty";
-}
-
-f();
-// Two objects are created and reference one another thus creating a cycle.
-// They will not get out of the function scope after the function call, so they
-// are effectively useless and could be free'd.
-// However, the reference-counting algorithm considers that since each of both
-// object is referenced at least once, none can be garbage-collected.
-
- -

Esempio reale

- -

Internet Explorer 6 e 7 sono conosciuti per avere un reference-counting garbage collector per gli oggetti DOM. I cicli di referenze sono errori comuni che possono generare uno spreco di memoria (memory leaks).

- -
var div;
-window.onload = function(){
-  div = document.getElementById("myDivElement");
-  div.circularReference = div;
-  div.lotsOfData = new Array(10000).join("*");
-};
-
- -

Nell'esempio precedente, l'elemento "myDivElement" ha una referenza circolare con se stesso nella proprietà "circularReference". Se la proprietà non è esplicitamente rimossa o annullata, un reference-counting garbage collector avrà sempre almeno una referenza intatta che manterrà l'elemento in memoria anche se esso fosse rimosso dal DOM. Se un oggetto trattiene molta memoria e ha almeno una referenza (come illustrato nell'esempio precedente con la proprietà "lotsOfData") la memoria da esso occupata non sarà mai rilasciata.

- -

L'algoritmo mark-and-sweep

- -

Questo algoritmo è il più famoso degli algoritmi di tracing; la tecnica del tracing è concettualmente molto semplice e si basa sulla definizione "quando un oggetto diventa irraggiungibile".

- -

Essa consiste nel prendere come riferimento gli oggetti root (indice dell'albero) e, partendo da essi, mediante una ricorsione, marcare (tramite un bit o una mappa distinta) tutti gli oggetti collegati tra loro da un riferimento. Al termine di questa operazione, gli oggetti raggiungibili saranno marcati mentre quelli non raggiungibili saranno eliminati.

- -

L'algoritmo mark-and-sweep (marca e butta via) si suddivide in due fasi: la prima fase (mark) nella quale l'algoritmo marca tutti gli oggetti che hanno almeno un riferimento attivo; nella seconda fase (sweep) nella quale tutti gli oggetti non marcati vengono liberati e la memoria viene restituita.

- -

A differenza della tecnica del reference counting il cui il costo dell'algoritmo è proporzionale all'ammontare del lavoro eseguito dal programma (ogni volta che si alloca/dealloca un oggetto bisogna creare-incrementare/decrementare il contatore), la tecnica del tracing è proporzionale alla dimensione della memoria ed è sicuramente più efficiente.

- -

I cicli non sono più un problema

- -

Nel primo esempio, dopo che la funzione ha restituito un risultato, i 2 oggetti non sono più referenziati da nessun altro oggetto raggiungibile dall'oggetto globale (root). Ne consegue che saranno irraggiungibili dal garbage collector e quindi eleminati.

- -

La stessa cosa accade con il secondo esempio. Una volta che il div e la sua variabile sono diventati irraggiungibili dalle radici, essi possono essere cancellati nonostante abbiano una referenza ciascuno.

- -

Limitazione: gli oggetti devono essere esplicitamente irragiungibili

- -

Sebbene sia marcata come una limitazione, è raramente raggiunta in pratica ed è anche il motivo per cui nessuno si preoccupa, di solito, dei garbage collector.

- -
-

Piccolo appunto italiano

- -

Tutte le parole tagliate sono state tradotte letteralmente ma in modo che la frase non perda di significato.

- -

cit. Il traduttore

-
- -

See also

- - diff --git a/files/it/web/javascript/getting_started/index.html b/files/it/web/javascript/getting_started/index.html deleted file mode 100644 index d9c0357ebb..0000000000 --- a/files/it/web/javascript/getting_started/index.html +++ /dev/null @@ -1,331 +0,0 @@ ---- -title: Getting Started (JavaScript Tutorial) -slug: Web/JavaScript/Getting_Started -translation_of: Learn/Getting_started_with_the_web/JavaScript_basics -translation_of_original: Web/JavaScript/Getting_Started ---- -

Perché JavaScript?

-

JavaScript è un linguaggio per computer potente, complicato, e spesso misconosciuto. Permette lo sviluppo rapido di applicazioni in cui gli utenti possono inserire i dati e vedere i risultati facilmente.

-

Il vantaggio primario di JavaScript, che è anche conosciuto come ECMAScript, è che è centrato intorno al Web browser, così da avere la capacità di produrre gli stessi risultati su tutte le piattaforme supportate dal browser. Gli esempi in questa pagina, proprio come Google Maps, girano su Linux, Windows, e OS X. Con la recente crescita di numerose librerie JavaScript è ora più facile traversare un documento, selezionare gli elementi del DOM, creare animazioni, trattare eventi, e sviluppare applicazioni Ajax. Diversamente dalla promozione intorno alle altre tecnologie spinta da vari interessi proprietari, JavaScript è realmente il solo linguaggio di programmazione "cross-platform" e "client-side" che è sia libero che universalmente adottato.

-

Cosa dovresti già conoscere

-

Iniziare a programmare con JavaScript è molto semplice. Tutto quello che serve per cominciare è un editor di testo e un Web browser.

-

Ci sono molte altre tecnologie che possono essere integrate e sviluppate insieme a Javascript che sono al di fuori di questo documento. Non aspettarti di fare un'intera applicazione come Google Maps tutta nel tuo primo giorno!

-

Come iniziare

-

Iniziare con JavaScript è molto semplice. Non devi aver precedentemente installato complicati programmi di sviluppo. Non devi conoscere come usare una shell, programmare Make, o usare un compilatore. JavaScript è interpretato dal tuo Web browser. Tutto quello che hai da fare è salvare il tuo programma come file testo e poi aprirlo nel tuo Web browser. E' tutto qui!

-

JavaScript è un linguaggio di programmazione ideale per linguaggi di computer introduttivi. Permette ai nuovi studenti di avere risposte immediate e insegna loro strumenti che essi troveranno di facile uso nella loro vita reale. Ciò è in assoluto contrasto con C, C++, and Java che sono veramente facili solo per sviluppatori software specializzati.

-

Browser compatibility issues

-

There are variations between what functionality is available in the different browsers. Mozilla, Chrome, Microsoft IE, Apple Safari, and Opera fluctuate in behavior. You can mitigate these issues by using the various cross-platform JavaScript APIs that are available. These APIs provide common functionality and hide these browser fluctuations from you.

-

How to try the examples

-

The examples below have some sample code. There are many ways to try these examples out. If you already have your own website, then you should be able to just save these examples as new Web pages on your website.

-

If you do not have your own website, you can save these examples as files on your computer and open them up with the Web browser you are using now. JavaScript is a very easy language to use for beginning programmers for this reason. You don't need a compiler or a development environment; you and your browser are all you need to get started!

-

You can also take use of some online programs like jsfiddle.net

-

Example: Catching a mouse click

-

The specifics of event handling (event types, handler registration, propagation, etc.) are too extensive to be fully covered in this simple example. However, this example cannot demonstrate catching a mouse click without delving a little into the JavaScript event system. Just keep in mind that this example will only graze the full details about JavaScript events and that if you wish to go beyond the basic capabilities described here, read more about the JavaScript event system.

-

'Mouse' events are a subset of the total events issued by a Web browser in response to user actions. The following is a list of the events emitted in response to a user's mouse action:

- -

Note that in the latest versions of HTML, the inline event handlers, i.e. the ones added as tag attributes, are expected to be all lowercase and that event handlers in script are always all lowercase.

-

The simplest method for capturing these events, to register event handlers - using HTML - is to specify the individual events as attributes for your element. Example:

-
  <span onclick="alert('Hello World!');">Click Here</span>
-

The JavaScript code you wish to execute can be inlined as the attribute value or you can call a function which has been defined in a <script> block within the HTML page:

-
<script>
-  function clickHandler() {
-     alert("Hello, World!");
-  }
-</script>
-<span onclick="clickHandler();">Click Here</span>
-

Additionally, the event object which is issued can be captured and referenced, providing the developer with access to specifics about the event such as which object received the event, the event's type, and which mouse button was clicked. Using the inline example again:

-
<script>
-  function clickHandler(event) {
-    var eType = event.type;
-    /* the following is for compatibility */
-    /* Moz populates the target property of the event object */
-    /* IE populates the srcElement property */
-    var eTarget = event.target || event.srcElement;
-
-    alert( "Captured Event (type=" + eType + ", target=" + eTarget + ")" );
-  }
-</script>
-<span onclick="clickHandler(event);">Click Here</span>
-

In addition to registering to receive events in your HTML, you can likewise set the same attributes of any HTMLElement objects generated by your JavaScript. The example below instantiates (creates) a span object, appends it to the page body, and registers the span object to receive mouse-over, mouse-out, mouse-down, and mouse-up events.

-
<body></body>
-<script>
-  function mouseeventHandler(event) {
-    /* The following is for compatibility */
-    /* IE does NOT by default pass the event object */
-    /* obtain a ref to the event if one was not given */
-    if (!event) event = window.event;
-
-    /* obtain event type and target as earlier */
-    var eType = event.type;
-    var eTarget = event.target || event.srcElement;
-    alert(eType +' event on element with id: '+ eTarget.id);
-  }
-
- function onloadHandler() {
-   /* obtain a ref to the 'body' element of the page */
-   var body = document.body;
-   /* create a span element to be clicked */
-   var span = document.createElement('span');
-   span.id = 'ExampleSpan';
-   span.appendChild(document.createTextNode ('Click Here!'));
-
-   /* register the span object to receive specific mouse events -
-      notice the lowercase of the events but the free choice in the names of the handlers you replace them with.
-   */
-   span.onmousedown = mouseeventHandler;
-   span.onmouseup = mouseeventHandler;
-   span.onmouseover = mouseeventHandler;
-   span.onmouseout = mouseeventHandler;
-
-   /* display the span on the page */
-   body.appendChild(span);
-}
-
-window.onload = onloadHandler; // since we replace the handler, we do NOT have () after the function name
-</script>
-

Example: Catching a keyboard event

-

Similar to the "Catching a mouse event" example above, catching a keyboard event relies on exploring the JavaScript event system. Keyboard events are fired whenever any key is used on the keyboard.

-

The list of available keyboard events emitted in response to a keyboard action is considerably smaller than those available for mouse:

- -

In a keypress event, the Unicode value of the key pressed is stored in either the keyCode or charCode property, never both. If the key pressed generates a character (e.g., 'a'), charCode is set to the code of that character, respecting the letter case (i.e., charCode takes into account whether the shift key is held down). Otherwise, the code of the pressed key is stored in keyCode.

-

The simplest method for capturing keyboard events is again to register event handlers within the HTML, specifying the individual events as attributes for your element. Example:

-
  <input type="text" onkeypress="alert ('Hello World!');">
-
-

As with mouse events, the JavaScript code you wish to execute can be inlined as the attribute value or you can call a function which has been defined in a <script> block within the HTML page:

-
<script>
-  function keypressHandler() {
-    alert ("Hello, World!");
-  }
-</script>
-
-<input onkeypress="keypressHandler();" />
-
-

Capturing the event and referencing the target (i.e., the actual key that was pressed) is achieved in a similar way to mouse events:

-
<script type="text/javascript">
-  function keypressHandler(evt) {
-      var eType = evt.type; // Will return "keypress" as the event type
-      /* here we again need to use a cross browser method
-         mozilla based browsers return which and others keyCode.
-         The Conditional operator or ternary is a good choice */
-      var keyCode = evt.which?evt.which:evt.keyCode;
-      var eCode = 'keyCode is ' + keyCode;
-      var eChar = 'charCode is ' + String.fromCharCode(keyCode); // or evt.charCode
-      alert ("Captured Event (type=" + eType + ", key Unicode value=" + eCode + ", ASCII value=" + eChar + ")");
-   }
-</script>
-<input onkeypress="keypressHandler(event);" />
-

Capturing any key event from the page can be done by registering the event at the document level and handling it in a function:

-
<script>
-  document.onkeypress = keypressHandler;
-  document.onkeydown = keypressHandler;
-  document.onkeyup = keypressHandler;
-</script>
-

Here is a complete example that shows key event handling:

-
<!DOCTYPE html>
-<html>
-<head>
-  <script>
-    var metaChar = false;
-    var exampleKey = 16;
-    function keyEvent(event) {
-      var key = event.keyCode || event.which; // alternative to ternary - if there is no keyCode, use which
-      var keychar = String.fromCharCode(key);
-      if (key == exampleKey) {
-        metaChar = true;
-      }
-      if (key != exampleKey) {
-         if (metaChar) {
-            alert("Combination of metaKey + " + keychar)
-            metaChar = false;
-         } else {
-           alert("Key pressed " + key);
-         }
-      }
-    }
-    function metaKeyUp(event) {
-      var key = event.keyCode || event.which;
-      if (key == exampleKey) { metaChar = false; }
-    }
-  </script>
-</head>
-<body onkeydown="keyEvent(event)" onkeyup="metaKeyUp(event)">
-    Try pressing any key!
-</body>
-</html>
-

Browser bugs and quirks

-

The two properties made available through the key events are keyCode and charCode. In simple terms, keyCode refers to the actual keyboard key that was pressed by the user, while charCode is intended to return that key's ASCII value. These two values may not necessarily be the same; for instance, a lower case 'a' and an upper case 'A' have the same keyCode, because the user presses the same key, but a different charCode because the resulting character is different.

-

The way in which browsers interpret the charCode is not a consistently-applied process. For example, Internet Explorer and Opera do not support charCode. However, they give the character information in keyCode, but only onkeypress. Onkeydown and onkeyup keyCode contain key information. Firefox uses a different word, "which", to distinguish the character.

-

Refer to the Mozilla Documentation on Keyboard Events for a further treatment of keyboard events.

-

{{ draft() }}

-

Example: Dragging images around

-

The following example allows moving the image of Firefox around the page:

-
<!DOCTYPE html>
-<html>
-<head>
-<style>
-img { position: absolute; }
-</style>
-
-<script>
-window.onload = function() {
-
-  movMeId = document.getElementById("ImgMov");
-  movMeId.style.top = "80px";
-  movMeId.style.left = "80px";
-
-  document.onmousedown = coordinates;
-  document.onmouseup = mouseup;
-
-  function coordinates(e) {
-    if (e == null) { e = window.event;}
-
-    // e.srcElement holds the target element in IE, whereas e.target holds the target element in Firefox
-    // Both properties return the HTML element the event took place on.
-
-    var sender = (typeof( window.event ) != "undefined" ) ? e.srcElement : e.target;
-
-    if (sender.id=="ImgMov") {
-      mouseover = true;
-      pleft = parseInt(movMeId.style.left);
-      ptop = parseInt(movMeId.style.top);
-      xcoor = e.clientX;
-      ycoor = e.clientY;
-      document.onmousemove = moveImage;
-      return false;
-    }
-    return false;
-  }
-
-  function moveImage(e) {
-    if (e == null) { e = window.event; }
-    movMeId.style.left = pleft+e.clientX-xcoor+"px";
-    movMeId.style.top = ptop+e.clientY-ycoor+"px";
-    return false;
-  }
-
-  function mouseup(e) {
-    document.onmousemove = null;
-  }
-}
-</script>
-</head>
-
-<body>
-  <img id="ImgMov" src="http://placehold.it/100x100&text=JS" width="64" height="64">
-  <p>Drag and drop around the image in this page.</p>
-</body>
-
-</html>
-

Example: Resizing things

-
- Example of resizing an image (the actual image is not resized, only the image's rendering.) -
  <!DOCTYPE html>
-  <html>
-    <head>
-      <style>
-        #resizeImage {
-          margin-left: 100px;
-        }
-      </style>
-      <script>
-      window.onload = function() {
-
-        var resizeId = document.getElementById("resizeImage");
-        var resizeStartCoordsX,
-            resizeStartCoordsY,
-            resizeEndCoordsX,
-            resizeEndCoordsY;
-
-        var resizeEndCoords;
-        var resizing = false;
-
-        document.onmousedown = coordinatesMousedown;
-        document.onmouseup = coordinatesMouseup;
-
-        function coordinatesMousedown(e) {
-          if (e == null) {
-            e = window.event;
-          }
-
-          var element = (typeof( window.event ) != 'undefined' ) ? e.srcElement : e.target;
-
-          if (element.id == "resizeImage") {
-            resizing = true;
-            resizeStartCoordsX = e.clientX;
-            resizeStartCoordsY = e.clientY;
-          }
-          return false;
-        }
-
-        function coordinatesMouseup(e) {
-          if (e == null) {
-            e = window.event;
-          }
-
-          if (resizing === true) {
-            var currentImageWidth = parseInt(resizeId.width);
-            var currentImageHeight = parseInt(resizeId.height);
-
-            resizeEndCoordsX = e.clientX;
-            resizeEndCoordsY = e.clientY;
-
-            resizeId.style.height = currentImageHeight - (resizeStartCoordsY - resizeEndCoordsY) + 'px';
-            resizeId.style.width = currentImageWidth - (resizeStartCoordsX - resizeEndCoordsX) + 'px';
-
-            resizing = false;
-          }
-          return false;
-        }
-      }
-      </script>
-    </head>
-
-    <body>
-      <img id="resizeImage" src="http://upload.wikimedia.org/wikipedia/commons/e/e7/Mozilla_Firefox_3.5_logo_256.png"
-width="64" height="64">
-      <p>Click on the image and drag for resizing.</p>
-    </body>
-
-  </html>
-
-

Example: Drawing Lines

-
<!DOCTYPE html>
-<html>
-<head>
-<script>
-function linedraw(ax,ay,bx,by)
-{
-    if(ay>by)
-    {
-        bx=ax+bx;
-        ax=bx-ax;
-        bx=bx-ax;
-        by=ay+by;
-        ay=by-ay;
-        by=by-ay;
-    }
-    var calc=Math.atan((ay-by)/(bx-ax));
-    calc=calc*180/Math.PI;
-    var length=Math.sqrt((ax-bx)*(ax-bx)+(ay-by)*(ay-by));
-    document.body.innerHTML += "<div id='line' style='height:" + length + "px;width:1px;background-color:black;position:absolute;top:" + (ay) + "px;left:" + (ax) + "px;transform:rotate(" + calc + "deg);-ms-transform:rotate(" + calc + "deg);transform-origin:0% 0%;-moz-transform:rotate(" + calc + "deg);-moz-transform-origin:0% 0%;-webkit-transform:rotate(" + calc  + "deg);-webkit-transform-origin:0% 0%;-o-transform:rotate(" + calc + "deg);-o-transform-origin:0% 0%;'></div>"
-}
-</script>
-</head>
-<body onload="linedraw(200,400,500,900);"> <!-- Replace with your co-ordinate -->
-</body>
-</html>
-

 

diff --git a/files/it/web/javascript/guida/controllo_del_flusso_e_gestione_degli_errori/index.html b/files/it/web/javascript/guida/controllo_del_flusso_e_gestione_degli_errori/index.html deleted file mode 100644 index 76e72f5cba..0000000000 --- a/files/it/web/javascript/guida/controllo_del_flusso_e_gestione_degli_errori/index.html +++ /dev/null @@ -1,461 +0,0 @@ ---- -title: Controllo del flusso di esecuzione e gestione degli errori -slug: Web/JavaScript/Guida/Controllo_del_flusso_e_gestione_degli_errori -tags: - - Controllo di flusso - - Guide - - JavaScript - - Principianti - - 'l10n:priority' -translation_of: Web/JavaScript/Guide/Control_flow_and_error_handling ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Grammar_and_types", "Web/JavaScript/Guide/Loops_and_iteration")}}
- -

JavaScript prevede un insieme di istruzioni compatto, specifico per il controllo del flusso di esecuzione, che si può utilizzare per aggiungere un'elevata interattività alle proprie applicazioni. Questo capitolo fornisce una panoramica su queste istruzioni.

- -

Il JavaScript reference contiene dettagli esaustivi sulle istruzioni di questo capitolo. Il carattere punto e virgola (;) è usato per separare le varie istruzioni del codice JavaScript.

- -

Ogni espressione JavaScript è a sua volta un'istruzione. Si veda a riguardo Espressioni ed operatori per una completa descrizione delle espressioni.

- -

Costrutto di blocco

- -

Un costrutto fondamentale è il blocco, usato per raggruppare insieme più istruzioni, delimitato da un paio di parentesi graffe ({}):

- -
{
-  istruzione_1;
-  istruzione_2;
-  .
-  .
-  .
-  istruzione_n;
-}
-
- -

Esempi

- -

Il blocco è comunemente usato assieme alle istruzioni per il controllo del flusso (e.g. if, for, while).

- -
while (x < 10) {
-  x++;
-}
-
- -

Qui, { x++; } rappresenta un blocco.

- -

Importante: JavaScript prima di ECMAScript2015 non aveva la visibilità di blocco. Le variabili definite nel blocco hanno una visibilità a livello di funzione o di script in cui sono contenute e l'effetto di assegnare loro un valore persiste oltre il blocco stesso. Cioè il blocco non definisce un campo di visibilità. I blocchi "Indipendenti" ("Standalone" blocks) in JavaScript possono dare un risultato differente da quello che avrebbero prodotto in C o in Java. Per esempio:

- -
var x = 1;
-{
-  var x = 2;
-}
-console.log(x); // produce 2
-
- -

Risulta 2 perché l'istruzione di definizione var x dentro il blocco ha lo stesso campo di visibilità dell'istruzione var x al di fuori del blocco. Mentre in C o Java, il codice equivalente avrebbe prodotto 1.

- -

A partire da ECMAScript2015, la dichiarazione di variabile con l'istruzione let ha visibilità di blocco. Si veda il riferimento a {{jsxref("Statements/let", "let")}} per ulteriori informazioni.

- -

Costrutti Condizionali

- -

Un costrutto condizionale è un insieme di istruzioni che vengono eseguite se una specifica condizione risulta vera. JavaScript prevede due costrutti condizionali: if...else e switch.

- -

Costrutto if...else

- -

Si usa il costrutto if per eseguire un blocco di istruzioni se una condizione logica è vera. Si usa la clausola opzionale else per eseguire istruzioni nel caso in cui la stessa condizione sia falsa. Un costrutto if...else si presenta come qui sotto:

- -
if (condizione) {
-  istruzioni_se_vera_la_condizione;
-} else {// opzionale
-  istruzioni_se_falsa_la_condizione;
-}
- -

Qui la condizione è qualsiasi espressione che sia valutabile come vera oppure falsa (true o false). Si veda il riferimento a Boolean per una spiegazione su cosa possa essere valutabile come true o false. Se la condizione viene valutata true, istruzioni_se_vera_la_condzione verrà eseguito, altrimenti verrà eseguito istruzioni_se_falsa_la_condzione. istruzioni_se_vera_la_condzione e istruzioni_se_falsa_la_condzione possono essere qualsiasi istruzione, incluso un altro if.

- -

Si possono pure combinare le istruizioni else if per testare molteplici condizioni in sequenza, come il seguente codice dimostra:

- -
if (condizione_1) {
-  istruzione_1;
-} else if (condizione_2) {
-  istruzione_2;
-} else if (condizione_n) {
-  istruzione_n;
-} else {
-  ultima_istruzione;
-}
-
- -

Nel caso di condizioni plurime solo la prima che sia valutata come vera sarà eseguita. Per eseguire più istruzioni si devono raggruppare in un blocco ({ ... }) . In generale è buona pratica usare un blocco specialmente se si usano if annidati:

- -
if (condizione) {
-  istruzione_1_eseguita_se_vera_la_condizione;
-  istruzione_2_eseguita_se_vera_la_condizione;
-  ...
-} else {
-  istruzione_3_eseguita_se_falsa_la_condizione;
-  istruzione_4_eseguita_se_falsa_la_condizione;
-  ...
-}
-
- -
Non è consigliabile usare la semplice assegnazione in una espressione condizionale, perché l'assegnamento potrebbe essere confuso con il segno di uguaglianza quando si dia un'occhiata rapida al codice. Ad esempio, non si usi il seguente codice:
- -
- -
if (x = y) {// questa è una assegnazione
-  /* istruzioni qui */
-}
- -

Se si deve proprio usare un assegnamento in una espressione condizionale è pratica comune aggiungere un paio di parentesi tonde attorno all'assegnamento. Per esempio:

- -
if ((x = y)) {
-  /* istruzioni qui */
-}
-
- -

Valori valutabili a false

- -

I seguenti valori si valutano a false (sono anche detti {{Glossary("Falsy")}} value):

- - - -

Tutti gli altri valori, inclusi gli oggetti, saranno valutati a true in una istruzione condizionale.

- -

Non si confonda il valori primitivi booleani true e false con i valori true e false dell'oggetto {{jsxref("Boolean")}}. Ad esempio:

- -
var b = new Boolean(false);
-
-if (b) // questa condizione è valutata a true
-       // perché 'b' in questo caso è un oggetto
-       // e si sa che tutti gli oggetti sono valutati a true
-
-if (b == true) // mentre questa a false,
-               // perché si va a prelevare il contenuto dell'oggetto 'b' che è false
-
- -

Esempi

- -

Nell'esempio a seguire la funzione controllaDati ritorna true se il numero di caratteri contenuti nella proprietà value dell'oggetto Text (treCaratteri) è tre, altrimenti mostra un popup di alert e, infine, ritorna il valore false.

- -
function controllaDati() {
-  if (document.form1.treCaratteri.value.length == 3) {
-    return true;
-  } else {
-    alert("Immetti esattemente tre caratteri. " +
-    document.form1.treCaratteri.value + " non è valido.");
-    return false;
-  }
-}
-
- -

Costrutto switch

- -

Un costrutto switch permette ad un programma di valutare un'espressione e tentare di trovare la corrispondenza esatta tra il valore risultante dalla valutazione dell'espressione e l'etichetta specificata nella clausola case. Se si incontra una corrisopondenza il programma eseguirà le istruzioni associate. Un costrutto switch si presenta  come nell'esempio qui sotto riportato:

- -
switch (espressione) {
-  case etichetta_1:
-    istruzione_1
-    [break;]// opzionale
-  case etichetta_2:
-    istruzione_2
-    [break;]
-    ...
-  default:
-    istruzioni_di_default
-    [break;]
-}
-
- -

Il programma cerca la prima corrispondenza tra il valore ottentuto della valutazione dell'espressione e l'etichetta nella clausola case, poi trasferisce il controllo al corpo della medesima clausola eseguendo le istruzioni relative. Se non è stata trovata alcuna corrispondeza il programma va alla clausola opzionale default e, se la trova, esegue le istruizioni ad essa relative. Se non è stata data alcuna clausola default il programma continuerà con l'istruzione successiva al blocco switch. La clausola default è l'ultima che appare nel blocco switch, ma questa è una convenzione non la regola.

- -

Il break opzionale, associato con ogni clausola case, assicura che il programma esca dal blocco switch una volta eseguite le istruzioni associate alla clausola e continui la sua esecuzione all'istruzione che segue il costrutto switch. Se il break è omesso il programma continua la sua esecuzione all'istruzione successiva nello stesso costrutto switch, ciò significa che eseguirà le istruzioni associate alla clausola case/default (se ci sono) successiva a quella appena terminata.

- -

Esempi

- -

Nel seguente esempio, se la variabile tipidifrutto contiene "Banane", il programma cercherà la corrispondente clausola case "Banane" ed eseguirà le istruzioni associate. Quando incontra il break, il porgramma esce dallo switch ed esegue l'istruzione successiva al blocco di switch. Se, invece, il break fosse stato omesso le istuzioni collegate con la clausola case "Ciliege" sarebbero state eseguite.

- -
switch (tipidifrutta) {
-  case "Arance":
-    console.log("Le Arance sono a €0.59 il chilo.");
-    break;
-  case "Mele":
-    console.log("Le mele sono a €0.32 il chilo.");
-    break;
-  case "Banane":
-    console.log("Le Banane sono €0.48 il chilo.");
-    break;
-  case "Ciliege":
-    console.log("Le ciliege sono s €3.00 il chilo.");
-    break;
-  case "Mango":
-    console.log("Il Mango è è €0.56 il chilo.");
-    break;
-  case "Papaia":
-    console.log("Il Mango e la Papaia sono a €2.79 il chilo.");
-    break;
-  default:
-    console.log("Spiacenti, abbiano terminato " + tipidifrutta + ".");
-}
-console.log("C'è qualcos'altro che ti piace?");
- -

Costrutti di gestione delle Eccezioni

- -

Si può sollevare/generare un'eccezione attraverso l'istruzione throw e si possono gestire usando il costrutto try...catch.

- - - -

Tipi di eccezione

- -

Quasi ogni tipo di oggetto può essere usato per sollevare/generare un'eccezione JavaScript. Tuttavia non tutti gli oggetti utili a questo scopo sono creati in modo eguale. Mentre è abbastanza comune usare numeri o stringhe per indicare un errore, è più efficace usare uno dei tipi di eccezione specificatamente creati a questo scopo:

- - - -

Istruzione throw

- -

Si usa l'istruzione throw per sollevare/generare un'eccezione. Quando si genera un'eccezione va specificata un'espressione che produca un valore da usarsi come eccezione:

- -
throw espressione;
-
- -

Si può usare una qualsiasi espressione con l'istruzione throw e non solamente espressioni di un certo tipo. Il seguente pezzo di codice lo dimostra:

- -
throw "Errore2";  // tipo String
-throw 42;         // tipo Number
-throw true;       // tipo Boolean
-throw {toString: function() { return "Sono un oggetto!"; } };
-
- -
Note: Si può specificare un oggetto quando si genera un'eccezione. Si può poi far riferimento alle proprietà dell'oggetto nel blocco catch. Il seguente esempio crea un oggetto myUserException del tipo UserException e lo usa nell'istruzione throw.
- -
// Crea un oggetto di tipo UserException
-function UserException(messaggio) {
-  this.message = messaggio;
-  this.name    = "UserException";
-}
-
-// Sovrascrive il metodo toString() affinché l'oggetto
-// dia una descrizione di se stesso al momento di usarlo come stringa.
-// (e.g. come messaggio nella console degli errori)
-UserException.prototype.toString = function() {
-  return this.name + ': "' + this.message + '"';
-}
-
-// Crea un'istanza dell'oggetto e lo usa nell'istruzione throw
-throw new UserException("Valore troppo alto!);
- -

Costrutto try...catch (... finally)

- -

Il costrutto try...catch racchiude un blocco di istruzioni, che potrebbero generare un'eccezione, e specifica uno o più azioni per gestire l'eccezione che potrebbe essere sollevata. Se viene sollevata un'eccezione il costrutto try...catch la cattura.

- -

Il costrutto try...catch è costituito da un blocco try, che contiene a sua volta uno o più istruzioni, e da al più (vedi nota più sotto) un blocco catch, contenenti istruzioni per gestire l'eccezione che eventulmente sarà sollevata all'interno del blocco try.  Cioè si vorrebbe che il blocco try fosse eseguito senza errori, ma se non fosse possibile si vuole che l'esecuzione passi al blocco catch. Se un'istruzione contenuta nel blocco (o in una funzione chiamata all'interno del blocco) try genera un'eccezione, il controllo passa immediatamente al blocco catch. Se nessuna eccezione è sollevata all'interno del blocco try, il blocco catch è semplicemente ignorato. Il blocco finally (opzionale se c'è il blocco catch, ma necessario se manca quest'utimo) è eseguito subito dopo l'esecuzione dei blocchi try/catch, ma prima di una qualsiasi istruzione che segua gli stessi try...catch...finally.

- -
-

In realtà il browser Firefox è in grado di suppostare i blocchi catch condizionati, oltre quello incondizionato, rendendo virtualmeente illimitata la definizione di più di un blocco catch per uno stesso blocco try. Tuttavia questa caratteristica non è standard e se ne scoraggia l'uso, si veda a proposito la referenza {{jsxref("Statements/try...catch", "try...catch")}}.

-
- -

L'esempio che segue usa il costrutto di try...catch. L'esempio chiama una funzione che ritorna il nome del mese estratto da un array grazie al parametro mo passato alla funzione. Se il valore passato non corrispondesse al numero di mese consentito (tra 1 e 12), un'eccezione verrebbe sollevata col valore "numeroMeseNonValido" e il blocco catch assegnerebbe alla variabile nomeDelMese il vaore di "sconoscuto".

- -
function getNomeDelMese(mo) {
-  mo = mo - 1; // Sistema il numero del mese (1 = Gen, 12 = Dic)
-  var mesi = ["Gen","Feb","Mar","Apr","Mag","Giu","Lug",
-                "Ago","Set","Ott","Nov","Dic"];
-  if (mesi[mo]) {
-    return mesi[mo];
-  } else {
-    throw "numeroMeseNonValido"; //l'istruzione throw è usata qui
-  }
-}
-
-try { // blocco try
-  nomeDelMese = getNomeDelMese(mese); // la funzione potrebbe sollevare un'eccezione
-}
-catch (eccezione) {
-  nomeDelMese = "sconosciuto";
-  logDegliErrori(eccezione); // Passa l'eccezione a un gestore -> una propria funzione
-
- -

Il blocco catch

- -

Si può usare il blocco catch per gestire le eccezioni che possono essere generate nel blocco try.

- -
catch (catchID) {
-  // istruzioni
-}
-
- -

Il blocco catch viene specificato un identificatore (catchID nel precedente esempio) che conterrà il valore specificato nell'istruzione throw. Si può usare questo identificatore per ottenere informazione ulteriori circa l'eccezione che è stata generata. JavaScript crea questo identificatore quando si entra nel blocco catch. L'identificatore è valido solo per la durata in esecuzione del blocco catch stesso, infatti usciti dal blocco catch termina la sua esistenza e non è più disponibile.

- -

Per esempio, il seguente codice solleva un'eccezione. Quando l'eccezione si realizza il controllo passa al blocco catch.

- -
try {
-  throw "miaEccezione"; // genera una eccezione
-}
-catch (eccezione) { // "eccezione" è l'identificatore con conterrà
-  // l'oggetto usato nell'istruzione thrown, in questo caso la stringa "miaEccezione"
-
-  // istruzioni che gestiscono l'eccezione
-  gestisciErrori(eccezione); // passa l'oggetto eccezione al gestore
-}
-
- -

Il blocco finally

- -

Il blocco finally contiene istruzioni che vengono eseguite subito dopo i blocchi try ed eventualmente catch, ma prima di ogni altra istruzione che segua il costrutto try...catch...finally. Il blocco finally è eseguito indipendentemente dal fatto che un'eccezione sia o meno generata. Se un'eccezione viene sollevata le istruzioni nel blocco finally saranno eseguite anche se il blocco catch corrispondente la gestisce.

- -

Si può usare il blocco finally per permettere agli script di terminare elegantemente in presenza di un'eccezione, ad esempio, se si deve liberare una risorsa che lo script trattiene. Il seguente esempio apre un file e lo usa (JavaScript lato server permette di accedere al file system). Se si solleva un'eccezione mentre il file è aperto il blocco finally chiude il file prima che lo script termini/fallisca.

- -
apriMioFile();
-try {
-  ScriviMioFile(dati); //Qui si può verificare un'eccezione/errore
-} catch(e) {
-  gestisciErrore(e); // Se avviene un errore lo si gestisce
-} finally {
-  chiudiMioFile(); // chiude comunque la risorsa
-}
-
- -

Se il blocco finally ritorna un valore questo diviene il valore ritornato dall'intero costrutto try-catch-finally a dispetto di qualsiasi valore eventualmente ritornato dai blocchi try/catch:

- -
function f() {
-  try {
-    console.log(0);
-    throw "fasulla";
-  } catch(e) {
-    console.log(1);
-    return true; // quasta istruzione di ritorno è sospesa
-                 // finché il blocco finally non termina
-    console.log(2); // istruzione non raggiungibile
-  } finally {
-    console.log(3);
-    return false; // sovrascrive il precedente "return"
-    console.log(4); // istruzione non raggiungibile
-  }
-  // "return false" è eseguito ora
-  console.log(5); // istruzione non raggiungibile
-}
-f(); // nel log a console troviamo stampato: 0, 1, 3 e false
-
- -

La sovrascrittura dei valori di ritorno, da parte del blocco finally, colpisce anche le eccezioni generate e/o ri-generate dentro il blocco catch:

- -
function f() {
-  try {
-    throw "fasulla";
-  } catch(e) {
-    console.log('catturata l\'eccezione interna "fasulla"');
-    throw e; // Quasta istruzione throw è sospesa
-             // finché il blocco finally non termina
-  } finally {
-    return false; // sovrascrive il precedente "throw"
-  }
-  // "return false" è eseguita ora
-}
-
-try {
-  f();
-} catch(e) {
-  // Questo blocco non sarà mai raggiunto in quanto l'istruzione
-  // throw dentro il blocco catch (vedi più sopra) è sovrascritta
-  // dal return della clausola finally
-  console.log('catturata l\'eccezione esterna "fasulla"');
-}
-
-// OUTPUT
-// catturata l'eccezione interna "fasulla"
- -

try...catch innestati

- -

Si possono annidare try...catch. Se un blocco try...catch interno non ha il blocco catch (in questo caso è d'obbligo che ci sia il blocco finally, anche vuoto, altrimenti si ha un errore sintattico), il blocco catch, del costrutto try...catch che lo racchiude, catturerà l'eventuale eccezione.

- -
try{// try-catch esterno
-  try{
-   // try-finally interno
-    throw "eccezione fasulla";
-  }
-  // Manca il blocco catch, ma deve esserci il blocco finally
-  finally{
-    // vuoto
-  }
-}
-catch(e){
-  // Viene catturata l'eccezione sollevata dal blocco più interno
-  console.log("cattura esterna: " + e);
-}
-
-//nella console sarà stampato: "cattura esterna: eccezione fasulla"
- -

Utilizzo degli oggetti Error

- -

A seconda del tipo di errore se si è in grado di usare le proprietà 'name' e 'message' si può avere un messaggio più ricco. 'name' fornisce la classe generale dell'Error (e.g., 'DOMException' o 'Error'), mentre 'message' generalmente fornisce un messaggio più conciso rispetto al convertire l'oggetto corrispondente all'errore in una stringa.

- -

Se si crea una propria eccezione affiché ci si avvantaggi di queste proprietà (come nel caso, ad esempio, del blocco catch che non discrimini tra l'oggetto rappresentante la propria eccezione e quello di sistema) si può usare il costruttore dell'oggetto Error:

- -
function faiQualcosaSoggettaAdErrore () {
-  if (codiceCheProduceUnErrore()) {
-    throw (new Error('Il Messaggio'));
-  } else {
-    faiQualcosaPerOttenereUnEorreDiJavascript();
-  }
-}
-....
-try {
-  faiQualcosaSoggettaAdErrore();
-} catch (e) {
-  console.log(e.name);    // Scrive a console: 'Error'
-  console.log(e.message); // Scrive a console: 'Il Messaggio' o un messaggio di errore di JavaScript)
-}
- -

I Promise

- -

A partire da ECMAScript2015, JavaScript acquisisce il supporto agli oggetti {{jsxref("Promise")}} permettendo di controllare l'esecuzione di operazioni in modo differito e asincrono.

- -

Un Promise può essere in uno di questi stati:

- - - -

- -

Caricare un'immagine con XHR

- -

Un esempio di semplice utilizzo di un Promise e XMLHttpRequest per caricare un'immagine è disponibile nel repository promise-test di MDN GitHub. Si può anche vedere in azione. Ogni passo  è commentato e ti permette di seguire il Promise e l'architettura XHR da vicino. Qui, invece, la versione non commentata che mostra l'utilizzo del Promise per darti un'idea del suo funzionamento:

- -
function caricaImmagine(url) {
-  return new Promise(function(resolve, reject) {
-    var request = new XMLHttpRequest();
-    request.open('GET', url);
-    request.responseType = 'blob';
-    request.onload = function() {
-      if (request.status === 200) {
-        resolve(request.response);
-      } else {
-        reject(Error('L\'immagine non è stata caricata con successo; codice di errore:'
-                     + request.statusText));
-      }
-    };
-    request.onerror = function() {
-      reject(Error('C\'è stato un errore di connessione'));
-    };
-    request.send();
-  });
-}
- -

Per informazioni più dettagliate si veda la pagina di riferimento relativa al {{jsxref("Promise")}}.

- -
{{PreviousNext("Web/JavaScript/Guide/Grammar_and_types", "Web/JavaScript/Guide/Loops_and_iteration")}}
diff --git a/files/it/web/javascript/guida/dettagli_object_model/index.html b/files/it/web/javascript/guida/dettagli_object_model/index.html deleted file mode 100644 index 1e2d4dc74f..0000000000 --- a/files/it/web/javascript/guida/dettagli_object_model/index.html +++ /dev/null @@ -1,727 +0,0 @@ ---- -title: Dettagli del modello a oggetti -slug: Web/JavaScript/Guida/Dettagli_Object_Model -tags: - - Guide - - Intermediate - - JavaScript -translation_of: Web/JavaScript/Guide/Details_of_the_Object_Model ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Working_with_Objects", "Web/JavaScript/Guide/Iterators_and_Generators")}}
- -
-

Il contenuto di questo articolo è in discussione. Lascia un feedback e aiutaci a rendere migliore questa pagina: {{bug(1201380)}}.

-
- -

JavaScript è un linguaggio ad oggetti basato su prototipi, piuttosto che sulle classi. A causa di questa diversa base, può essere meno evidente come JavaScript permette di creare gerarchie di oggetti e di avere l'ereditarietà delle proprietà e dei loro valori. Questo articolo cerca di chiarire questo aspetto.

- -

Questo capitolo presuppone una certa familiarità con JavaScript e con l'uso delle funzioni per la creazione di semplici oggetti.

- -

Linguaggi class-based vs. linguaggi prototype-based

- -

I linguaggi ad oggetti basati su classi, come Java e C++, si basano su due entità distinte: le classi (classes) e le istanze (instances).

- - - -

Un linguaggio basato su prototipi, come JavaScript, non fa questa distinzione: ha solo oggetti. Introduce la nozione di oggetto prototipo (prototypical object), un oggetto usato come modello da cui prendere le proprietà iniziali per un nuovo oggetto. Ogni oggetto può specificare le sue proprietà, anche quando viene creato o in fase di esecuzione.Inoltre, ogni oggetto può essere associato ad un altro oggetto come prototipo, consentendo al secondo oggetto di condividere le proprietà del primo.

- -

Definizione di una classe

- -

Nei linguaggi basati su classi, le classi vengono definite in class definition separate. In queste definizioni è possibile specificare metodi speciali, chiamari costruttori (constructors), per creare istanze della classe. Un costruttore può specificare i valori iniziali per le proprietà dell'istanza ed eseguire altre elaborazioni adatte al momento della creazione. Per creare le istanze di una classe si utilizza l'operatore new associato al metodo costruttore.

- -

JavaScript segue un modello simile, ma non prevede la definizione della classe separata dal costruttore. Invece, per creare oggetti con un particolare set di proprietà e valori si definisce una funzione costruttore. Ogni funzione JavaScript può essere usata come costruttore. Per creare un nuovo oggetto si utilizza l'operatore new associato a una funzione costruttore.

- -

Sottoclassi e ereditarietà

- -

In un linguaggio basato su classi, si crea una gerarchia tra le classi attraverso le definizioni delle classi stesse. All'interno della definizione di una classe è possibile specificare che la nuova classe è una sottoclasse (subclass) di una classe esistente. La sottoclasse eredita tutte le proprietà della superclasse e può inoltre aggiungere nuove proprietà o modificare quelle ereditate. Per esempio, assumiamo che la classe Employee include solo le proprietà name e dept, e Manager è una sottoclasse di Employee che aggiunge la proprietà reports. In questo caso, un'istanza della classe Manager avrà tutte e tre le proprietà: name, dept, e reports.

- -

JavaScript implementa l'ereditarietà permettendo di associare un oggetto prototipo ad ogni funzione costruttore. Quindi, è possibile ricreare esattamente l'esempio visto in precedenza, ma usando una terminologia leggermente diversa. Innanzitutto  si definisce la funzione costruttore Employee, specificando le proprietà name e dept. In seguito, si definisce la funzione costruttore Manager, chiamando il costruttore Employee e specificando la proprietà reports. Infine, si assegna a un nuovo oggetto derivato da Employee.prototype come il prototipo per la funzione costruttore Manager. Quando si crea un nuovo Manager, questo eredita le proprietà name e dept dall'oggetto Employee.

- -

Aggiungere e rimuovere proprietà

- -

Nei linguaggi basati su classi, una classe viene solitamente creata in fase di compilazione mentre le istanze possono essere create in fase di compilazione o in fase di esecuzione. Non è possibile cambiare il numero o il tipo di proprietà di una classe dopo che questa è stata definita. In JavaScript in fase di esecuzione si possono aggiungere o rimuovere proprietà a qualunque oggetto. Se si aggiunge una proprietà a un oggetto che è usato come prototipo per un gruppo di oggetti, anche gli oggetti del gruppo ereditano la nuova proprietà.

- -

Riepilogo delle differenze

- -

La tabella seguente fornisce un breve riepilogo di alcune di queste differenze. Il resto di questo capitolo descrive nel detteglio l'uso in JavaScript di costruttori e prototipi per creare una gerarchia di oggetti e lo confronta con la procedura che si userebbe in Java.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Confronto tra il sistema di oggetti basato su classi (Java) e il sistema di oggetti basato su prototipi (JavaScript)
Class-based (Java)Prototype-based (JavaScript)
Classi e istanze sono entità separate.Tutti gli oggetti possono ereditare da un altro oggetto.
Definire una classe con una definizione; istanziare una classe con un metodo costruttoreDefinire e creare una collezione di oggetti con una funzione costruttore.
Creare un singolo oggetto con l'operatore new.Uguale.
Costruire una gerarchia di oggetti usando la definizione di classe per definire le sottoclassi di classi esistenti.Costruire una gerarchia di oggetti assegnando un oggetto come prototipo associato a una funzione costruttore.
Ereditare le proprietà seguendo la catena delle classi.Ereditare le proprietà seguendo la catena dei prototipi.
La definizione di classe specifica tutte le proprietà di tutte le istanze della classe. Non è possibile aggiungere proprietà dinamicamente durante l'esecuzione.La funzione costruttore o il prototipo specificano un set iniziale di proprietà. È possibile aggiungere o rimuovere dinamicamente proprietà ai singoli oggetti o all'intero gruppo di oggetti.
- -

L'esempio 'dipendente'

- -

Il resto di questo capitolo usa la gerarchia dei dipendenti mostrata nella figura seguente.

- -
-
-

Una semplice gerarchia con gli oggetti seguenti:

- -

-
- -
-
    -
  • Employee ha le proprietà name (il cui valore di default è una stringa vuota) e dept (il cui valore di default è "general").
  • -
  • Manager è basato su Employee. Aggiunge la proprietà reports  (il cui valore di default è un array vuoto, destinato a contenere una serie di oggetti Employee).
  • -
  • WorkerBee è anch'esso basato su Employee. Aggiunge la proprietà projects (il cui valore di default è un array vuoto, destinato a contenere una serie di stringhe).
  • -
  • SalesPerson è basato su WorkerBee. Aggiunge la proprietà quota (il cui valore di default è 100). Sovrascrive inoltre la proprietà dept con il valore "sales", che indica che tutti i venditori si trovano nello stesso dipartimento.
  • -
  • Engineer è basato su WorkerBee. Aggiunge la proprietà machine (il cui valore di default è una stringa vuota) e sovrascrive la proprietà dept con il valore "engineering".
  • -
-
-
- -

Creazione della gerarchia

- -

Ci sono diversi modi per definire una funzione costruttore appropriata per implementare la gerarchia dei dipendenti. Il modo scelto per definirli dipende molto da cosa si vuole riuscire a fare nella propria applicazione.

- -

Questa sezione mostra come usare definizioni molto semplici (e relativamente rigide) per dimostrare come far funzionare l'ereditarietà. In queste definizioni, quando si crea un oggetto non è possibile specificare il valore di nessuna proprietà. L'oggetto creato avrà semplicemente i valori di default, che potranno essere cambiati in un secondo momento.

- -

In una applicazione reale, probabilmente si vorranno definire dei costruttori che permettono di impostare i valori delle proprietà mentre si crea un oggetto (per maggiori informazioni si veda la sezione Costruttori più flessibili). Per adesso, queste semplici definizioni dimostrano come le proprietà vengono ereditate.

- -

Le seguenti definizioni Java e JavaScript di Employee sono simili. L'unica differenza è che in Java si ha la necessità di specificare il tipo di ogni proprietà (questo è dovuto al fatto che Java è un linguaggio fortemente tipizzato mentre JavaScript è un linguaggio a tipizzazione dinamica.

- -
-

JavaScript

- -
function Employee() {
-  this.name = "";
-  this.dept = "general";
-}
-
- -

Java

- -
public class Employee {
-   public String name = "";
-   public String dept = "general";
-}
-
-
- -

Le definizioni di Manager e WorkerBee mostrano la differenza nel modo di specificare l'oggetto seguente che si trova più in alto nella catena di ereditarietà. In JavaScript si aggiunge un'istanza prototipo come valore della proprietà prototype della funzione costrutore. È possibile farlo in qualsiasi momento dopo aver definito il costruttore. In Java, si specifica la superclasse all'interno della definizione della classe. Non è possibile cambiare la superclasse all'esterno della definizione.

- -
-

JavaScript

- -
function Manager() {
-  Employee.call(this);
-  this.reports = [];
-}
-Manager.prototype = Object.create(Employee.prototype);
-
-function WorkerBee() {
-  Employee.call(this);
-  this.projects = [];
-}
-WorkerBee.prototype = Object.create(Employee.prototype);
-
- -

Java

- -
public class Manager extends Employee {
-   public Employee[] reports = new Employee[0];
-}
-
-
-
-public class WorkerBee extends Employee {
-   public String[] projects = new String[0];
-}
-
-
-
-
- -

Le definizioni di Engineer e SalesPerson creano oggetti che discendono da  WorkerBee, e quindi da Employee. Un oggetto di questo tipo ha le proprietà di tutti gli oggetti che si trovano sopra di esso nella catena. Inoltre, queste definizioni sovrascrivono il valore ereditato delle proprietà  dept con nuovi valori specifici per questi oggetti.

- -
-

JavaScript

- -
function SalesPerson() {
-   WorkerBee.call(this);
-   this.dept = "sales";
-   this.quota = 100;
-}
-SalesPerson.prototype = Object.create(WorkerBee.prototype);
-
-function Engineer() {
-   WorkerBee.call(this);
-   this.dept = "engineering";
-   this.machine = "";
-}
-Engineer.prototype = Object.create(WorkerBee.prototype);
-
- -

Java

- -
public class SalesPerson extends WorkerBee {
-   public String dept = "sales";
-   public double quota = 100.0;
-}
-
-
-public class Engineer extends WorkerBee {
-   public String machine;
-   public String dept = "engineering";
-   public String machine = "";
-}
-
-
-
- -

Usando queste definizioni è possibile creare istanze di questi oggetti che ricevono i valori di default delle loro proprietà. La figura seguente illustra l'utilizzo di queste definizioni JavaScript per creare nuovi oggetti e mostra i valori delle diverse proprietà per questi nuovi oggetti.

- -
-

Nota: Il termine istanza ha uno specifico significato tecnico nei linguaggi basati su classi. In questi linguaggi, un'istanza è una singola istanziazione di una classe ed è fondamentalmente differente dala classe. In JavaScript, "istanza" non ha questo significato tecnico perché JavaScript non ha questa differenza tra classi e istanze. Tuttavia, parlando di JavaScript, "istanza" può essere usato in modo informale per riferirsi a un oggetto creato usando una particolare funzione costruttore. Quindi, in questo esempio, è possibile dire che jane è un'istanza di Engineer. Allo stesso modo, sebbene i termini genitore  (parent), figlio (child), antenato (ancestor) e discendente (descendant) non hanno un significato conenzionale in JavaScript, possono essere usati in modo informale per riferirsi a oggetti che si trovano più o meno in alto nella catena dei prototipi.

-
- -

Creazione di oggetti con definizioni semplici

- -
-

Gerarchia degli oggetti

- -

La gerarchia seguente è creata usando il codice sulla destra.

- -

- -

 

- -

singoli oggetti

- -
var jim = new Employee;
-// jim.name is ''
-// jim.dept is 'general'
-
-var sally = new Manager;
-// sally.name is ''
-// sally.dept is 'general'
-// sally.reports is []
-
-var mark = new WorkerBee;
-// mark.name is ''
-// mark.dept is 'general'
-// mark.projects is []
-
-var fred = new SalesPerson;
-// fred.name is ''
-// fred.dept is 'sales'
-// fred.projects is []
-// fred.quota is 100
-
-var jane = new Engineer;
-// jane.name is ''
-// jane.dept is 'engineering'
-// jane.projects is []
-// jane.machine is ''
-
-
- -

Proprietà degli oggetti

- -

Questa sezione spiega come gli oggetti ereditano le proprietà da altri oggetti presenti nella catena dei prototipi e cosa succede quando viene aggiunta una proprietà in fase di esecuzione.

- -

Ereditare le proprietà

- -

Supponiamo di creare un nuovo oggetto WorkerBee chiamato mark con l'istruzione seguente:

- -
var mark = new WorkerBee;
-
- -

Quando JavaScript vede l'operatore new, crea un nuovo oggeto generico e lo passa come valore della parola chiave this nella funzione costruttore WorkerBee. La funzione costruttore imposta esplicitamente il valore della proprietà projects e implicitamente il valore della proprietà interna __proto__ uguale al valore WorkerBee.prototype. (Il nome di questa proprietà ha due underscores iniziali e due finali). La proprietà __proto__ determina la catena di prototipi usata per restituire i valori delle proprietà. Una volta che queste proprietà sono impostate, JavaScript restituisce il nuovo oggetto e l'istruzione di assegnazione imposta la variabile mark per questo oggetto.

- -

Questo processo non inserisce esplicitamente valori nell'oggetto mark (valori locali) per le proprietà che l'oggetto eredita dalla catena dei prototipi. Quando si richiede un valore di una proprietà, JavaScript prima controlla se il valore è presente nell'oggetto. Se c'è, viene restituito quel valore. Se il valore non è presente a livello locale, JavaScript controlla la catena dei prototipi (sfruttando la proprietà __proto__). Se un oggetto nella catena dei prototipi ha un valore per la proprietà, viene restituito. Se non viene trovata la proprietà, JavaScript risponde che l'oggetto non ha la proprietà cercata. In questo modo, l'oggetto mark ha le seguenti propietà con i rispettivi valori:

- -
mark.name = "";
-mark.dept = "general";
-mark.projects = [];
-
- -

L'oggetto mark eredita i valori per le proprietà name e dept dall'oggetto prototipo presente in mark.__proto__. Il costruttore WorkerBee assegna un valore locale per la proprietà projects. L'ereditarietà di proprietà e valori in JavaScript fnziona in questo modo. Alcune sottigliezze su questo processo sono trattate nella sezione Ereditare le proprietà (revisited).

- -

Poiché questi costruttori non permettono di fornire valori specifici per una singola istanza, questa informazione è generica. I valori delle proprietà sono quelli di default condivisi da tutti i nuovi oggetti creati da WorkerBee. È oviamente possibile cambiare i valori di ognuna di queste proprietà. È quindi possibile assegnare informazioni specifice per mark nel modo seguente:

- -
mark.name = "Doe, Mark";
-mark.dept = "admin";
-mark.projects = ["navigator"];
- -

Aggiungere proprietà

- -

In JavaScript, è possibile aggiungere proprietà a qualsiasi oggetto in fase di esecuzione. Non si è costretti ad usare solo le proprietà fornite dalla funzione costruttore. Per aggiungere una proprietà che sia specifica per un singolo oggetto, si deve assegnare il valore all'oggetto nel modo seguente::

- -
mark.bonus = 3000;
-
- -

Ora, l'oggetto markha una proprietà bonus, ma nessun altro WorkerBee ha questa proprietà.

- -

Se si aggiunge una nuova proprietà a un oggetto che viene usato come prototipo per una funzione costruttore, la proprietà sarà aggiunta a tutti gli oggetti che ereditano le proprietà dal prototipo. Per esempio, è possibile aggiungere la proprietà specialty a tutti i dipendenti con l'istruzione seguente:

- -
Employee.prototype.specialty = "none";
-
- -

Non appena JavaScript esegue questa istruzione, anche l'oggetto mark avrà la proprietà specialty con il valore "none". La figura seguente mostra cosa succede qunado questa proprietà viene aggiunta al prototipo Employee e in seguito la si sovrascrive per il prototipo Engineer.

- -


- Aggiungere le proprietà

- -

Costruttori più flessibili

- -

Le funzioni costruttore mostrate finora non permettono di specificare i valori delle proprietà qunado viene creata un'istanza. Come in Java, è possibile fornire argomenti al costruttore per inizializzare i valori delle proprietà per le istanze. La figura seguente mostra un modo per farlo.

- -


- Specificare le proprietà in un costruttore, modo 1

- -

La tabella seguente mostra le definizioni di questi oggetti in JavaScript e in Java.

- -
-

JavaScript

- -

Java

-
- -
-
function Employee (name, dept) {
-  this.name = name || "";
-  this.dept = dept || "general";
-}
-
- -

 

- -

 

- -

 

- -

 

- -
public class Employee {
-   public String name;
-   public String dept;
-   public Employee () {
-      this("", "general");
-   }
-   public Employee (String name) {
-      this(name, "general");
-   }
-   public Employee (String name, String dept) {
-      this.name = name;
-      this.dept = dept;
-   }
-}
-
-
- -
-
function WorkerBee (projs) {
-
- this.projects = projs || [];
-}
-WorkerBee.prototype = new Employee;
-
- -

 

- -

 

- -
public class WorkerBee extends Employee {
-   public String[] projects;
-   public WorkerBee () {
-      this(new String[0]);
-   }
-   public WorkerBee (String[] projs) {
-      projects = projs;
-   }
-}
-
-
- -
-
-function Engineer (mach) {
-   this.dept = "engineering";
-   this.machine = mach || "";
-}
-Engineer.prototype = new WorkerBee;
-
- -

 

- -

 

- -
public class Engineer extends WorkerBee {
-   public String machine;
-   public Engineer () {
-      dept = "engineering";
-      machine = "";
-   }
-   public Engineer (String mach) {
-      dept = "engineering";
-      machine = mach;
-   }
-}
-
-
- -

Queste definizioni JavaScript usano un linguaggio speciale per impostare i valori di default:

- -
this.name = name || "";
-
- -

In JavaScript l'operatore logico OR (||) valuta il suo primo argomento. Se questa espressione può essere convertita a true, l'operatore restituisce il primo argomento. Altrimenti l'operatore restituisce il valore del secondo argomento. Quindi, questa linea di codice verifica se name ha un valore utile per la proprietà name. Se ce l'ha, imposta this.name a questo valore. Altrimenti, imposta this.name a una stringa vuota. Questo capitolo usa questo linguaggio per brevità, comunque può disorientare a prima vista.

- -
-

Nota: Potrebbe non funzionare come atteso se la funzione costruttore è chiamata con un argomento che converte a false (come ad esempio 0 (zero) o una stringa vuota ("")). In questo caso verrà scelto il valore di default.

-
- -

Con queste definizioni, quando si crea un'istanza di un oggetto, è possibile specificare i valori per le proprietà definite localmente. Per creare un nuovo Engineer è possibile utilizzare l'espressione seguente:

- -
var jane = new Engineer("belau");
-
- -

Le proprietà di Jane sono ora:

- -
jane.name == "";
-jane.dept == "engineering";
-jane.projects == [];
-jane.machine == "belau"
-
- -

È da notare che con queste definizioni non è possibile specificare una valore iniziale per le proprietà ereditate, come ad esempio name. Se si desidera specificare un valore iniziale per una proprietà ereditata, in JavaScript è necessario aggiungere ulteriore codice alla funzione costruttore.

- -

Finora, la funzione costruttore ha creato un oggetto generico e poi ha specificato proprietà locali e valori per il nuovo oggetto. È possibile fare in modo che il costruttore aggiunga più proprietà chiamando direttamente la funzione costruttore per un oggetto che si trova a un livello più alto nella catena dei prototipi. La figura seguente mostra queste nuove definizioni.

- -


- Specificare le proprietà in un costruttore, modo 2

- -

Guardiamo nel dettaglio una di queste definizioni. Ecco la nuova definizione per il costruttore Engineer:

- -
function Engineer (name, projs, mach) {
-  this.base = WorkerBee;
-  this.base(name, "engineering", projs);
-  this.machine = mach || "";
-}
-
- -

Supponiamo di creare un nuovo oggetto Engineer nel modo seguente:

- -
var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
-
- -

JavaScript segue questa procedura:

- -
    -
  1. L'operatore new crea un oggetto generico e imposta il valore Engineer.prototype per la sua proprietà __proto__.
  2. -
  3. L'operatore new passa il nuovo oggetto come valore della parola chiave this nella funzione costruttore Engineer.
  4. -
  5. Il costruttore crea una nuova proprietà per l'oggetto chiamata base e assegna il valore del costruttore WorkerBee alla proprietà base. Questo rende il costruttore WorkerBee un metode dell'oggetto Engineer. Il nome della proprietà base non è peculiare. È possibile usare qualsiasi nome per la proprietà; base è semplicemente evocativo dello scopo.
  6. -
  7. Il costruttore chiama il metodo base, passando come suoi argomenti due degli argomenti passati al costruttore ("Doe, Jane" e ["navigator", "javascript"]) e anche la stringa "engineering". Usando esplicitamente "engineering" nel costruttore indica che tutti gli oggetti Engineer hanno lo stesso valore per la proprietà dept ereditata, e questo valore sovrascrive il valore ereditato dal costruttore Employee.
  8. -
  9. Poiché base è un metodo di Engineer, all'interno della chiamata di base, JavaScript aggiunge la parola chiave this all'oggetto creato al passaggio 1. In questo modo, la funzione WorkerBee a sua volta passa gli argomenti "Doe, Jane" e "engineering" alla funzione costruttore Employee. Dopo l'esecuzione della funzione costruttore Employee, la funzione WorkerBee utilizza l'argomento rimanente per impostare la proprietà projects.
  10. -
  11. Dopo l'esecuzione del metodo base, il costruttore Engineer inizializza la proprietà machine dell'oggetto al valore "belau".
  12. -
  13. Dopo l'esecuzione del costruttore, JavaScript assegna il nuovo oggetto alla variabile jane.
  14. -
- -

Avendo chiamato il costruttore WorkerBee dall'interno del costruttore Engineer, si potrebbe pensare di aver impostato in modo corretto l'ereditarietà per gli oggetti Engineer. Questo non è il caso. Chiamare il costruttore WorkerBee assicura che un oggetto Engineer venga creato con le proprietà specificate in tutte le funzioni costruttore che sono chiamate. Però, se in un secondo momento vengono aggiunte proprietà ai prototipi Employee o WorkerBee, queste proprietà non saranno ereditate dall'oggetto Engineer. Per esempio, se si considera il codice seguente:

- -
function Engineer (name, projs, mach) {
-  this.base = WorkerBee;
-  this.base(name, "engineering", projs);
-  this.machine = mach || "";
-}
-var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
-Employee.prototype.specialty = "none";
-
- -

L'oggetto jane non eredita la proprietà specialty. È comunque necessario impostare esplicitamente il prototipo per garantire l'ereditarietà dinamica. Se si considera invece l'esempio seguente:

- -
function Engineer (name, projs, mach) {
-  this.base = WorkerBee;
-  this.base(name, "engineering", projs);
-  this.machine = mach || "";
-}
-Engineer.prototype = new WorkerBee;
-var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
-Employee.prototype.specialty = "none";
-
- -

Adesso il valore per l'oggetto jane della proprietà specialty è "none".

- -

Un altro modo per ereditare le proprietà è l'utilizzo dei metodi call() e apply(). Gli esempi sottostanti si equivalgono:

- -
-
function Engineer (name, projs, mach) {
-  this.base = WorkerBee;
-  this.base(name, "engineering", projs);
-  this.machine = mach || "";
-}
-
- -
function Engineer (name, projs, mach) {
-  WorkerBee.call(this, name, "engineering", projs);
-  this.machine = mach || "";
-}
-
-
- -

L'utilizzo del metodo call() costituisce un'implementazione più pulita poiché la proprietà base non è più necessaria.

- -

Ereditare le proprietà (revisited)

- -

Le sezioni precedenti descrivono come i costruttori e i prototipi consentono di avere gerarchia ed ereditarietà in JavaScript. Questa sezione espone alcune sottiglienzze che non erano necessariamente evidenti nelle discussioni precedenti.

- -

Valori locali vs. valori ereditati

- -

Quando si accede a una proprietà di un oggetto, JavaScript esegue i seguenti passaggi, come descritto in precedenza in questo capitolo:

- -
    -
  1. Verifica se il valore è presente a livello locale. Se c'è, restituisce quel valore.
  2. -
  3. Se non è presente, verifica la catena dei prototipi (usando la proprietà __proto__).
  4. -
  5. Se un oggetto nella catena dei prototipi ha un valore per la proprietà specificata, restituisce quel valore.
  6. -
  7. Se la proprietà non viene trovata, l'oggetto non ha la proprietà.
  8. -
- -

Il risultato di questo processo dipende da come sono stati definiti gli elementi. L'esempio iniziale aveva queste definizioni:

- -
function Employee () {
-  this.name = "";
-  this.dept = "general";
-}
-
-function WorkerBee () {
-  this.projects = [];
-}
-WorkerBee.prototype = new Employee;
-
- -

Con queste definizioni, si supponga di creare amy come un'istanza di WorkerBee con la seguente istruzione:

- -
var amy = new WorkerBee;
-
- -

L'oggetto amy ha una proprietà locale, projects. I valori per le proprietà name e dept non sono specifici per amy e quindi derivano dalla proprietà __proto__ dell'oggetto amy. Quindi, amy ha i seguenti valori:

- -
amy.name == "";
-amy.dept == "general";
-amy.projects == [];
-
- -

Ora si supponga di cambiare il valore della proprietà name nel prototipo associato con Employee:

- -
Employee.prototype.name = "Unknown"
-
- -

Ci si potrebbe aspettare che il nuovo valore si propaghi a tutte le istanze di Employee. Invece, non lo fa.

- -

Quando si crea qualsiasi istanza dell'oggetto Employee, questa istanza riceve un valore locale per la proprietà name (la stringa vuota). Questo significa che quando si imposta il prototipo WorkerBee creando un nuovo oggetto Employee, WorkerBee.prototype avrà un valore locale per la proprietà name. Quindi, quando JavaScript legge la proprietà name dell'oggetto amy (istanza di WorkerBee), trova in WorkerBee.prototype il valore locale di questa proprietà. Pertanto non continua a cercare nella catena salendo a Employee.prototype.

- -

Se si vuole cambiare il valore di una proprietà di un oggetto in fase di esecuzione e si vuole che il nuovo valore venga ereditato da tutti i discendenti dell'oggetto, non è possibile definire la proprietà all'interno della funzione costruttore dell'oggetto. Invece, si aggiunge la proprietà al prototipo associato al costruttore. Per esempio, assumiamo di cambiare il codice precedente con quello che segue:

- -
function Employee () {
-  this.dept = "general";    // Note that this.name (a local variable) does not appear here
-}
-Employee.prototype.name = "";    // A single copy
-
-function WorkerBee () {
-  this.projects = [];
-}
-WorkerBee.prototype = new Employee;
-
-var amy = new WorkerBee;
-
-Employee.prototype.name = "Unknown";
-
- -

In questo caso, il valore della proprietà name di amy diventa "Unknown".

- -

Come mostra questo esempio, se si vogliono avere i valori di default per le proprietà dell'oggetto e si vuole avere la possibilità di cambiare questi valori in fase di esecuzione, si devono impostare le proprietà nel prototipo del costruttore, e non direttamente nella funzione costruttore.

- -

Determinazione delle relazioni tra istanze

- -

In JavaScript la ricerca delle proprietà (property lookup) controlla prima tra le proprietà specifiche dell'oggetto e, se il nome della proprietà non viene trovato, controlla la proprietà speciale __proto__. Il processo, chiamato "ricerca nella catena dei prototipi" (lookup in the prototype chain), continua ricorsivamente .

- -

Quando un oggetto viene costruito, la proprietà speciale __proto__ viene impostata al valore della proprietà prototype del costruttore. L'espressione new Foo() crea un oggetto con __proto__ == Foo.prototype. Di conseguenza, le modifiche alle proprietà di Foo.prototype alterano la ricerca delle proprietà per tutti gli oggetti che sono stati creati con new Foo().

- -

Ogni oggetto ha una proprietà __proto__ (ad eccezione di Object); ogni funzione ha una proprietà prototype. Quindi gli oggetti possono essere correlati ad altri oggetti attraverso una 'ereditarietà prototipale' (prototypal inheritance). È possibile verificare l'ereditarietà confrontando la proprietà __proto__ di un oggetto con l'oggetto prototype di una funzione. JavaScript fornisce una scorciatoia: l'operatore instanceof confronta un oggetto con una funzione e restituisce true se l'oggetto eredita dal prototipo della funzione. Per esempio,

- -
var f = new Foo();
-var isTrue = (f instanceof Foo);
- -

Per un esempio più dettagliato, supponiamo di avere lo stesso gruppo di definizioni visto nella sezione For a more detailed example, suppose you have the same set of definitions shown in Ereditare le proprietà. Creiamo un oggetto Engineer nel modo seguente:

- -
var chris = new Engineer("Pigman, Chris", ["jsd"], "fiji");
-
- -

Per questo oggetto, tutti gli enunciati seguenti sono veri:

- -
chris.__proto__ == Engineer.prototype;
-chris.__proto__.__proto__ == WorkerBee.prototype;
-chris.__proto__.__proto__.__proto__ == Employee.prototype;
-chris.__proto__.__proto__.__proto__.__proto__ == Object.prototype;
-chris.__proto__.__proto__.__proto__.__proto__.__proto__ == null;
-
- -

Dato ciò, è possibile scrivere una funzione instanceOf come segue:

- -
function instanceOf(object, constructor) {
-   object = object.__proto__;
-   while (object != null) {
-      if (object == constructor.prototype)
-         return true;
-      if (typeof object == 'xml') {
-        return constructor.prototype == XML.prototype;
-      }
-      object = object.__proto__;
-   }
-   return false;
-}
-
- -
-

Nota: L'implementazione vista sopra verifica se l'oggetto è di tipo "xml" per ovviare a una stranezza nel modo in cui gli oggetti XML sono rappresentati nelle versioni recenti di JavaScript. Per i dettagli essenziali si veda il {{ bug(634150) }}.

-
- -

Se si utilizza la funzione instanceOf definita in precedenza, queste espressioni sono vere:

- -
instanceOf (chris, Engineer)
-instanceOf (chris, WorkerBee)
-instanceOf (chris, Employee)
-instanceOf (chris, Object)
-
- -

Ma l'espressione seguente è falsa:

- -
instanceOf (chris, SalesPerson)
-
- -

Informazioni globali nei costruttori

- -

Quando vengono creati dei costruttori, è necessario essere scrupolosi se si impostano informazioni globali all'interno del costruttore. Per esempio, se si vuole che un ID univoco venga assegnato automaticamente a ogni nuovo Employee si potrebbe usare la definizione seguente:

- -
var idCounter = 1;
-
-function Employee (name, dept) {
-   this.name = name || "";
-   this.dept = dept || "general";
-   this.id = idCounter++;
-}
-
- -

Con questa definizione, quando viene creato un nuovo Employee, il costruttore assegna l'ID seguente e incrementa il contatore globale (idCounter). Così, se l'istruzione successiva è la seguente, l'ID di victoria sarà 1, l'ID di harry sarà 2:

- -
var victoria = new Employee("Pigbert, Victoria", "pubs")
-var harry = new Employee("Tschopik, Harry", "sales")
-
- -

Questa a prima vista potrebbe sembrare la procedura corretta. Tuttavia, il contatore globale idCounter viene incrementato ogni volta che viene creato un oggetto Employee, per qualsiasi scopo. Se viene creata l'intera gerarchia di oggetti Employee mostrata in questo capitolo, il costruttore Employee viene chiamato ogni volta che si definisce un prototipo. Supponiamo di avere il codice seguente:

- -
var idCounter = 1;
-
-function Employee (name, dept) {
-   this.name = name || "";
-   this.dept = dept || "general";
-   this.id = idCounter++;
-}
-
-function Manager (name, dept, reports) {...}
-Manager.prototype = new Employee;
-
-function WorkerBee (name, dept, projs) {...}
-WorkerBee.prototype = new Employee;
-
-function Engineer (name, projs, mach) {...}
-Engineer.prototype = new WorkerBee;
-
-function SalesPerson (name, projs, quota) {...}
-SalesPerson.prototype = new WorkerBee;
-
-var mac = new Engineer("Wood, Mac");
-
- -

Si assuma inoltre che le definizioni omesse abbiano la proprietà base e chiamino il costruttore che si trova al livello superiore nella catena dei prototipi. In questo caso, nel momento in cui viene creato l'oggetto mac, il valore di mac.id sarà 5.

- -

A seconda dell'applicazione, può essere più o meno importante che il valore del contatore sia stato incrementato queste volte aggiuntive. Se interessa il valore esatto di questo contatore, una soluzione possibile può prevedere l'uso del costruttore seguente al posto di quello visto in precedenza:

- -
function Employee (name, dept) {
-   this.name = name || "";
-   this.dept = dept || "general";
-   if (name)
-      this.id = idCounter++;
-}
-
- -

Quando viene creata un'istanza di Employee che deve essere usata come prototipo, non vengono forniti argomenti al costruttore. Usando questa definizione del costruttore, quando non vengono inseriti argomenti, il costruttore non assegna un valore all'ID e non aggiorna il contatore. Quindi, affinché a un oggetto Employee venga assegnato un ID, è necesario specificare un nome per il dipendente. In questo esempio, l'ID di mac sarà 1.

- -

JavaScript non supporta l'ereditarietà multipla

- -

Alcuni linguaggi ad oggetti ammettono l'ereditarietà multipla. Ossia, un oggetto può ereditare proprietà e valori da oggetti genitori non correlati. Javascript non supporta l'ereditarietà multipla.

- -

L'eredità dei valori delle proprietà si ha in fase di esecuzione quando JavaScript cerca attraverso la catena dei prototipo di un oggetto per trovare un valore. Poiché un oggetto ha un unico prototipo associato, JavaScript non può ereditare dinamicamente da più di una catena di prototipi.

- -

In JavaScript, è possibile che una funzione costruttore chiami al suo interno diverse funzioni costruttore. Questo dà l'illusione dell'ereditarietà multipla. Per esempio consideriamo le istruzioni seguenti:

- -
function Hobbyist (hobby) {
-   this.hobby = hobby || "scuba";
-}
-
-function Engineer (name, projs, mach, hobby) {
-   this.base1 = WorkerBee;
-   this.base1(name, "engineering", projs);
-   this.base2 = Hobbyist;
-   this.base2(hobby);
-   this.machine = mach || "";
-}
-Engineer.prototype = new WorkerBee;
-
-var dennis = new Engineer("Doe, Dennis", ["collabra"], "hugo")
-
- -

Assumiamo inoltre che la definizione di WorkerBee sia quella usata in precedenza in questo capitolo. In questo caso, l'oggetto dennis avrà queste proprietà:

- -
dennis.name == "Doe, Dennis"
-dennis.dept == "engineering"
-dennis.projects == ["collabra"]
-dennis.machine == "hugo"
-dennis.hobby == "scuba"
-
- -

Quindi dennis riceve la proprietà hobby dal costruttore Hobbyist. Però, se in seguito si aggiunge una proprietà al prototipo del costruttore Hobbyist:

- -
Hobbyist.prototype.equipment = ["mask", "fins", "regulator", "bcd"]
-
- -

L'oggetto dennis non erediterà questa nuova proprietà.

- -
{{PreviousNext("Web/JavaScript/Guide/Working_with_Objects", "Web/JavaScript/Guide/Iterators_and_Generators")}}
diff --git a/files/it/web/javascript/guida/espressioni_regolari/index.html b/files/it/web/javascript/guida/espressioni_regolari/index.html deleted file mode 100644 index f876045948..0000000000 --- a/files/it/web/javascript/guida/espressioni_regolari/index.html +++ /dev/null @@ -1,647 +0,0 @@ ---- -title: Espressioni regolari -slug: Web/JavaScript/Guida/Espressioni_Regolari -translation_of: Web/JavaScript/Guide/Regular_Expressions ---- -
{{jsSidebar("Guida JavaScript")}} {{PreviousNext("Web/JavaScript/Guide/Text_formatting", "Web/JavaScript/Guide/Indexed_collections")}}
- -

Le espressioni regolari sono schemi usati per confrontare combinazioni di caratteri nelle stringhe. In JavaScript, le espressioni regolari sono anche oggetti. Questi pattern sono usati con i metodi {{jsxref("RegExp.exec", "exec()")}} e {{jsxref("RegExp.test", "test()")}} della classe {{jsxref("RegExp")}}, e con i metodi {{jsxref("String.match", "match()")}},   {{jsxref("String.matchAll", "matchAll()")}}, {{jsxref("String.replace", "replace()")}}, {{jsxref("String.search", "search()")}}, e {{jsxref("String.split", "split()")}} della classe {{jsxref("String")}}. Questo capitolo descrive le espressioni regolari in JavaScript.

- -

Creazione di un'espressione regolare

- -

Puoi creare un'espressione regolare in uno dei seguenti modi:

- - - -

Scrivere uno schema per espressioni regolari

- -

Uno schema di espressione regolare è composto da caratteri semplici, come /abc/, o da una combinazione di caratteri semplici e speciali, come /ab*c//Chapter (\d+)\.\d*/. L'ultimo esempio include parentesi che sono usate come un dispositivo di memoria. Il confronto fatto con queste parti dello schema è ricordato per usi futuri, come descritto in  {{ web.link("#Using_parenthesized_substring_matches", "Using parenthesized substring matches") }}.

- -
-

Nota: Se hai già familiarità con la struttura di un'espressione regolare, potresti anche leggere il cheatsheet per una rapida ricerca di un modello/costrutto specifico

-
- -

Usare modelli semplici

- -

I modelli semplici sono costituiti da carattrei per i quali si desidera trovare una corrispondenza diretta. Ad esempio, il modello /abc/ corrisponde solo quando esattamente i caratteri "abc" si presentano insieme e in quell'ordine. Una tale corrispondenza avrebbe successo nelle stringhe "Ciao, conosci il tuo abc?" e "Gli ultimi progetti di aeroplani si sono evoluti da slabcraft". In entrambi i casi la corrispondenza con la sottostringa "abc" avviene. Non c'è corrispondenza nella stringa "Grab crab" perché invece di contenere l'esatta sottostringa "abc" coniente la sottostringa "ab c".

- -

Usare caratteri speciali

- -

Quando la ricerca di una corrispondenza richiede qualcosa di più di una corrispondenza diretta, come la ricerca di una o più b o la ricerca di spazi bianchi, il modello include caratteri speciali. Ad esempio, per abbinare una singola "a" seguita da zero o più "b" seguita da "c", dovresti usare il modello /ab*c/: il * dopo "b" significa "0 o più occorrenze dell'elemento precedente". Nella stringa "cbbabbbbcdebc", questo modello corrisponderà alla sottostringa "abbbbc".
-
- La tabella seguente fornisce un elenco completo e una descrizione dei caratteri speciali che possono essere utilizzati nelle espressioni regolari.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Caratteri speciali nelle espressioni regolari
CarattereSignificato/Utilizzo
\ -

Matches according to the following rules:
-
- A backslash that precedes a non-special character indicates that the next character is special and is not to be interpreted literally. For example, a 'b' without a preceding '\' generally matches lowercase 'b's wherever they occur. But a '\b' by itself doesn't match any character; it forms the special word boundary character.
-
- A backslash that precedes a special character indicates that the next character is not special and should be interpreted literally. For example, the pattern /a*/ relies on the special character '*' to match 0 or more a's. By contrast, the pattern /a\*/ removes the specialness of the '*' to enable matches with strings like 'a*'.
-
- Do not forget to escape \ itself while using the RegExp("pattern") notation because \ is also an escape character in strings.

-
^Matches beginning of input. If the multiline flag is set to true, also matches immediately after a line break character.
-
- For example, /^A/ does not match the 'A' in "an A", but does match the 'A' in "An E".
-
- The '^' has a different meaning when it appears as the first character in a character set pattern. See complemented character sets for details and an example.
$ -

Matches end of input. If the multiline flag is set to true, also matches immediately before a line break character.

- -

For example, /t$/ does not match the 't' in "eater", but does match it in "eat".

-
* -

Matches the preceding expression 0 or more times. Equivalent to {0,}.

- -

For example, /bo*/ matches 'boooo' in "A ghost booooed" and 'b' in "A bird warbled", but nothing in "A goat grunted".

-
+ -

Matches the preceding expression 1 or more times. Equivalent to {1,}.

- -

For example, /a+/ matches the 'a' in "candy" and all the a's in "caaaaaaandy", but nothing in "cndy".

-
?Matches the preceding expression 0 or 1 time. Equivalent to {0,1}.
-
- For example, /e?le?/ matches the 'el' in "angel" and the 'le' in "angle" and also the 'l' in "oslo".
-
- If used immediately after any of the quantifiers *, +, ?, or {}, makes the quantifier non-greedy (matching the fewest possible characters), as opposed to the default, which is greedy (matching as many characters as possible). For example, applying /\d+/ to "123abc" matches "123". But applying /\d+?/ to that same string matches only the "1".
-
- Also used in lookahead assertions, as described in the x(?=y) and x(?!y) entries of this table.
-  
. -

(The decimal point) matches any single character except the newline character.

- -

For example, /.n/ matches 'an' and 'on' in "nay, an apple is on the tree", but not 'nay'.

-
(x) -

Matches 'x' and remembers the match, as the following example shows. The parentheses are called capturing parentheses.
-
- The '(foo)' and '(bar)' in the pattern /(foo) (bar) \1 \2/ match and remember the first two words in the string "foo bar foo bar". The \1 and \2 in the pattern match the string's last two words. Note that \1, \2, \n are used in the matching part of the regex. In the replacement part of a regex the syntax $1, $2, $n must be used, e.g.: 'bar foo'.replace( /(...) (...)/, '$2 $1' ).

-
(?:x)Matches 'x' but does not remember the match. The parentheses are called non-capturing parentheses, and let you define subexpressions for regular expression operators to work with. Consider the sample expression /(?:foo){1,2}/. If the expression was /foo{1,2}/, the {1,2} characters would apply only to the last 'o' in 'foo'. With the non-capturing parentheses, the {1,2} applies to the entire word 'foo'.
x(?=y) -

Matches 'x' only if 'x' is followed by 'y'. This is called a lookahead.

- -

For example, /Jack(?=Sprat)/ matches 'Jack' only if it is followed by 'Sprat'. /Jack(?=Sprat|Frost)/ matches 'Jack' only if it is followed by 'Sprat' or 'Frost'. However, neither 'Sprat' nor 'Frost' is part of the match results.

-
x(?!y) -

Matches 'x' only if 'x' is not followed by 'y'. This is called a negated lookahead.

- -

For example, /\d+(?!\.)/ matches a number only if it is not followed by a decimal point. The regular expression /\d+(?!\.)/.exec("3.141") matches '141' but not '3.141'.

-
x|y -

Matches either 'x' or 'y'.

- -

For example, /green|red/ matches 'green' in "green apple" and 'red' in "red apple."

-
{n}Matches exactly n occurrences of the preceding expression. N must be a positive integer.
-
- For example, /a{2}/ doesn't match the 'a' in "candy," but it does match all of the a's in "caandy," and the first two a's in "caaandy."
{n,m} -

Where n and m are positive integers and n <= m. Matches at least n and at most m occurrences of the preceding expression. When m is omitted, it's treated as ∞.

- -

For example, /a{1,3}/ matches nothing in "cndy", the 'a' in "candy," the first two a's in "caandy," and the first three a's in "caaaaaaandy". Notice that when matching "caaaaaaandy", the match is "aaa", even though the original string had more a's in it.

-
[xyz]Character set. This pattern type matches any one of the characters in the brackets, including escape sequences. Special characters like the dot(.) and asterisk (*) are not special inside a character set, so they don't need to be escaped. You can specify a range of characters by using a hyphen, as the following examples illustrate.
-
- The pattern [a-d], which performs the same match as [abcd], matches the 'b' in "brisket" and the 'c' in "city". The patterns /[a-z.]+/ and /[\w.]+/ match the entire string "test.i.ng".
[^xyz] -

A negated or complemented character set. That is, it matches anything that is not enclosed in the brackets. You can specify a range of characters by using a hyphen. Everything that works in the normal character set also works here.

- -

For example, [^abc] is the same as [^a-c]. They initially match 'r' in "brisket" and 'h' in "chop."

-
[\b]Matches a backspace (U+0008). You need to use square brackets if you want to match a literal backspace character. (Not to be confused with \b.)
\b -

Matches a word boundary. A word boundary matches the position where a word character is not followed or preceeded by another word-character. Note that a matched word boundary is not included in the match. In other words, the length of a matched word boundary is zero. (Not to be confused with [\b].)

- -

Examples:
- /\bm/ matches the 'm' in "moon" ;
- /oo\b/ does not match the 'oo' in "moon", because 'oo' is followed by 'n' which is a word character;
- /oon\b/ matches the 'oon' in "moon", because 'oon' is the end of the string, thus not followed by a word character;
- /\w\b\w/ will never match anything, because a word character can never be followed by both a non-word and a word character.

- -
-

Note: JavaScript's regular expression engine defines a specific set of characters to be "word" characters. Any character not in that set is considered a word break. This set of characters is fairly limited: it consists solely of the Roman alphabet in both upper- and lower-case, decimal digits, and the underscore character. Accented characters, such as "é" or "ü" are, unfortunately, treated as word breaks.

-
-
\B -

Matches a non-word boundary. This matches a position where the previous and next character are of the same type: Either both must be words, or both must be non-words. The beginning and end of a string are considered non-words.

- -

For example, /\B../ matches 'oo' in "noonday", and /y\B./ matches 'ye' in "possibly yesterday."

-
\cX -

Where X is a character ranging from A to Z. Matches a control character in a string.

- -

For example, /\cM/ matches control-M (U+000D) in a string.

-
\d -

Matches a digit character. Equivalent to [0-9].

- -

For example, /\d/ or /[0-9]/ matches '2' in "B2 is the suite number."

-
\D -

Matches any non-digit character. Equivalent to [^0-9].

- -

For example, /\D/ or /[^0-9]/ matches 'B' in "B2 is the suite number."

-
\fMatches a form feed (U+000C).
\nMatches a line feed (U+000A).
\rMatches a carriage return (U+000D).
\s -

Matches a single white space character, including space, tab, form feed, line feed. Equivalent to [ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff].

- -

For example, /\s\w*/ matches ' bar' in "foo bar."

-
\S -

Matches a single character other than white space. Equivalent to [^ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff].

- -

For example, /\S\w*/ matches 'foo' in "foo bar."

-
\tMatches a tab (U+0009).
\vMatches a vertical tab (U+000B).
\w -

Matches any alphanumeric character including the underscore. Equivalent to [A-Za-z0-9_].

- -

For example, /\w/ matches 'a' in "apple," '5' in "$5.28," and '3' in "3D."

-
\W -

Matches any non-word character. Equivalent to [^A-Za-z0-9_].

- -

For example, /\W/ or /[^A-Za-z0-9_]/ matches '%' in "50%."

-
\n -

Where n is a positive integer, a back reference to the last substring matching the n parenthetical in the regular expression (counting left parentheses).

- -

For example, /apple(,)\sorange\1/ matches 'apple, orange,' in "apple, orange, cherry, peach."

-
\0Matches a NULL (U+0000) character. Do not follow this with another digit, because \0<digits> is an octal escape sequence.
\xhhMatches the character with the code hh (two hexadecimal digits)
\uhhhhMatches the character with the code hhhh (four hexadecimal digits).
\u{hhhh}(only when u flag is set) Matches the character with the Unicode value hhhh (hexadecimal digits).
- -

Escaping user input to be treated as a literal string within a regular expression can be accomplished by simple replacement:

- -
function escapeRegExp(string){
-  return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
-}
- -

Using parentheses

- -

Parentheses around any part of the regular expression pattern cause that part of the matched substring to be remembered. Once remembered, the substring can be recalled for other use, as described in {{ web.link("#Using_parenthesized_substring_matches", "Using Parenthesized Substring Matches") }}.

- -

For example, the pattern /Chapter (\d+)\.\d*/ illustrates additional escaped and special characters and indicates that part of the pattern should be remembered. It matches precisely the characters 'Chapter ' followed by one or more numeric characters (\d means any numeric character and + means 1 or more times), followed by a decimal point (which in itself is a special character; preceding the decimal point with \ means the pattern must look for the literal character '.'), followed by any numeric character 0 or more times (\d means numeric character, * means 0 or more times). In addition, parentheses are used to remember the first matched numeric characters.

- -

This pattern is found in "Open Chapter 4.3, paragraph 6" and '4' is remembered. The pattern is not found in "Chapter 3 and 4", because that string does not have a period after the '3'.

- -

To match a substring without causing the matched part to be remembered, within the parentheses preface the pattern with ?:. For example, (?:\d+) matches one or more numeric characters but does not remember the matched characters.

- -

Lavorare con le espressioni regolari

- -

Le espressioni regolari sono usate con i metodi test and exec di RegExp e con i metodi match, replace, search, and split di String .Questi metodi sono spiegati in dettaglio nelle  JavaScript reference.

- -

Metodi che usano le espressioni regolari

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MetodoDescrizione
{{jsxref("RegExp.exec", "exec")}} -

Un metodo di RegExp che esegue una ricerca per una corrispondenza in una stringa. Ritorna un array di informazioni, o null se non trova corrispondenze.

-
{{jsxref("RegExp.test", "test")}}Un metodo di RegExp che testa le corrispondenze in una stinga. Ritorna true o false. 
{{jsxref("String.match", "match")}}Un metodo di String che esegue una ricerca per una corrispondenza in una stringa. Ritorna un array di informazioni, o null se non trova corrispondenze.
{{jsxref("String.search", "search")}}A String method that tests for a match in a string. It returns the index of the match, or -1 if the search fails.
{{jsxref("String.replace", "replace")}}A String method that executes a search for a match in a string, and replaces the matched substring with a replacement substring.
{{jsxref("String.split", "split")}}A String method that uses a regular expression or a fixed string to break a string into an array of substrings.
- -

When you want to know whether a pattern is found in a string, use the test or search method; for more information (but slower execution) use the exec or match methods. If you use exec or match and if the match succeeds, these methods return an array and update properties of the associated regular expression object and also of the predefined regular expression object, RegExp. If the match fails, the exec method returns null (which coerces to false).

- -

In the following example, the script uses the exec method to find a match in a string.

- -
var myRe = /d(b+)d/g;
-var myArray = myRe.exec("cdbbdbsbz");
-
- -

If you do not need to access the properties of the regular expression, an alternative way of creating myArray is with this script:

- -
var myArray = /d(b+)d/g.exec("cdbbdbsbz"); // equivalent to "cdbbdbsbz".match(/d(b+)d/g);
-
- -

If you want to construct the regular expression from a string, yet another alternative is this script:

- -
var myRe = new RegExp("d(b+)d", "g");
-var myArray = myRe.exec("cdbbdbsbz");
-
- -

With these scripts, the match succeeds and returns the array and updates the properties shown in the following table.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Results of regular expression execution.
ObjectProperty or indexDescriptionIn this example
myArrayThe matched string and all remembered substrings.["dbbd", "bb"]
indexThe 0-based index of the match in the input string.1
inputThe original string."cdbbdbsbz"
[0]The last matched characters."dbbd"
myRelastIndexThe index at which to start the next match. (This property is set only if the regular expression uses the g option, described in {{ web.link("#Advanced_searching_with_flags", "Advanced Searching With Flags") }}.)5
sourceThe text of the pattern. Updated at the time that the regular expression is created, not executed."d(b+)d"
- -

As shown in the second form of this example, you can use a regular expression created with an object initializer without assigning it to a variable. If you do, however, every occurrence is a new regular expression. For this reason, if you use this form without assigning it to a variable, you cannot subsequently access the properties of that regular expression. For example, assume you have this script:

- -
var myRe = /d(b+)d/g;
-var myArray = myRe.exec("cdbbdbsbz");
-console.log("The value of lastIndex is " + myRe.lastIndex);
-
-// "The value of lastIndex is 5"
-
- -

However, if you have this script:

- -
var myArray = /d(b+)d/g.exec("cdbbdbsbz");
-console.log("The value of lastIndex is " + /d(b+)d/g.lastIndex);
-
-// "The value of lastIndex is 0"
-
- -

The occurrences of /d(b+)d/g in the two statements are different regular expression objects and hence have different values for their lastIndex property. If you need to access the properties of a regular expression created with an object initializer, you should first assign it to a variable.

- -

Using parenthesized substring matches

- -

Including parentheses in a regular expression pattern causes the corresponding submatch to be remembered. For example, /a(b)c/ matches the characters 'abc' and remembers 'b'. To recall these parenthesized substring matches, use the Array elements [1], ..., [n].

- -

The number of possible parenthesized substrings is unlimited. The returned array holds all that were found. The following examples illustrate how to use parenthesized substring matches.

- -

The following script uses the {{jsxref("String.replace", "replace()")}} method to switch the words in the string. For the replacement text, the script uses the $1 and $2 in the replacement to denote the first and second parenthesized substring matches.

- -
var re = /(\w+)\s(\w+)/;
-var str = "John Smith";
-var newstr = str.replace(re, "$2, $1");
-console.log(newstr);
-
- -

This prints "Smith, John".

- -

Advanced searching with flags

- -

Regular expressions have four optional flags that allow for global and case insensitive searching. These flags can be used separately or together in any order, and are included as part of the regular expression.

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
Regular expression flags
FlagDescription
gGlobal search.
iCase-insensitive search.
mMulti-line search.
yPerform a "sticky" search that matches starting at the current position in the target string. See {{jsxref("RegExp.sticky", "sticky")}}
- -

To include a flag with the regular expression, use this syntax:

- -
var re = /pattern/flags;
-
- -

or

- -
var re = new RegExp("pattern", "flags");
-
- -

Note that the flags are an integral part of a regular expression. They cannot be added or removed later.

- -

For example, re = /\w+\s/g creates a regular expression that looks for one or more characters followed by a space, and it looks for this combination throughout the string.

- -
var re = /\w+\s/g;
-var str = "fee fi fo fum";
-var myArray = str.match(re);
-console.log(myArray);
-
- -

This displays ["fee ", "fi ", "fo "]. In this example, you could replace the line:

- -
var re = /\w+\s/g;
-
- -

with:

- -
var re = new RegExp("\\w+\\s", "g");
-
- -

and get the same result.

- -

The m flag is used to specify that a multiline input string should be treated as multiple lines. If the m flag is used, ^ and $ match at the start or end of any line within the input string instead of the start or end of the entire string.

- -

Examples

- -

The following examples show some uses of regular expressions.

- -

Changing the order in an input string

- -

The following example illustrates the formation of regular expressions and the use of string.split() and string.replace(). It cleans a roughly formatted input string containing names (first name first) separated by blanks, tabs and exactly one semicolon. Finally, it reverses the name order (last name first) and sorts the list.

- -
// The name string contains multiple spaces and tabs,
-// and may have multiple spaces between first and last names.
-var names = "Harry Trump ;Fred Barney; Helen Rigby ; Bill Abel ; Chris Hand ";
-
-var output = ["---------- Original String\n", names + "\n"];
-
-// Prepare two regular expression patterns and array storage.
-// Split the string into array elements.
-
-// pattern: possible white space then semicolon then possible white space
-var pattern = /\s*;\s*/;
-
-// Break the string into pieces separated by the pattern above and
-// store the pieces in an array called nameList
-var nameList = names.split(pattern);
-
-// new pattern: one or more characters then spaces then characters.
-// Use parentheses to "memorize" portions of the pattern.
-// The memorized portions are referred to later.
-pattern = /(\w+)\s+(\w+)/;
-
-// New array for holding names being processed.
-var bySurnameList = [];
-
-// Display the name array and populate the new array
-// with comma-separated names, last first.
-//
-// The replace method removes anything matching the pattern
-// and replaces it with the memorized string—second memorized portion
-// followed by comma space followed by first memorized portion.
-//
-// The variables $1 and $2 refer to the portions
-// memorized while matching the pattern.
-
-output.push("---------- After Split by Regular Expression");
-
-var i, len;
-for (i = 0, len = nameList.length; i < len; i++){
-  output.push(nameList[i]);
-  bySurnameList[i] = nameList[i].replace(pattern, "$2, $1");
-}
-
-// Display the new array.
-output.push("---------- Names Reversed");
-for (i = 0, len = bySurnameList.length; i < len; i++){
-  output.push(bySurnameList[i]);
-}
-
-// Sort by last name, then display the sorted array.
-bySurnameList.sort();
-output.push("---------- Sorted");
-for (i = 0, len = bySurnameList.length; i < len; i++){
-  output.push(bySurnameList[i]);
-}
-
-output.push("---------- End");
-
-console.log(output.join("\n"));
-
- -

Using special characters to verify input

- -

In the following example, the user is expected to enter a phone number. When the user presses the "Check" button, the script checks the validity of the number. If the number is valid (matches the character sequence specified by the regular expression), the script shows a message thanking the user and confirming the number. If the number is invalid, the script informs the user that the phone number is not valid.

- -

Within non-capturing parentheses (?: , the regular expression looks for three numeric characters \d{3} OR | a left parenthesis \( followed by three digits \d{3}, followed by a close parenthesis \), (end non-capturing parenthesis )), followed by one dash, forward slash, or decimal point and when found, remember the character ([-\/\.]), followed by three digits \d{3}, followed by the remembered match of a dash, forward slash, or decimal point \1, followed by four digits \d{4}.

- -

The Change event activated when the user presses Enter sets the value of RegExp.input.

- -
<!DOCTYPE html>
-<html>
-  <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-    <meta http-equiv="Content-Script-Type" content="text/javascript">
-    <script type="text/javascript">
-      var re = /(?:\d{3}|\(\d{3}\))([-\/\.])\d{3}\1\d{4}/;
-      function testInfo(phoneInput){
-        var OK = re.exec(phoneInput.value);
-        if (!OK)
-          window.alert(phoneInput.value + " isn't a phone number with area code!");
-        else
-          window.alert("Thanks, your phone number is " + OK[0]);
-      }
-    </script>
-  </head>
-  <body>
-    <p>Enter your phone number (with area code) and then click "Check".
-        <br>The expected format is like ###-###-####.</p>
-    <form action="#">
-      <input id="phone"><button onclick="testInfo(document.getElementById('phone'));">Check</button>
-    </form>
-  </body>
-</html>
-
- -
{{PreviousNext("Web/JavaScript/Guide/Text_formatting", "Web/JavaScript/Guide/Indexed_collections")}}
diff --git a/files/it/web/javascript/guida/functions/index.html b/files/it/web/javascript/guida/functions/index.html deleted file mode 100644 index 4aca8d5a7b..0000000000 --- a/files/it/web/javascript/guida/functions/index.html +++ /dev/null @@ -1,646 +0,0 @@ ---- -title: Funzioni -slug: Web/JavaScript/Guida/Functions -translation_of: Web/JavaScript/Guide/Functions ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Loops_and_iteration", "Web/JavaScript/Guide/Expressions_and_Operators")}}
- -
 
- -

Le funzioni sono tra i blocchi di programmazione fondamentali in JavaScript. Una funzione è una procedura JavaScript — un gruppo di istruzioni ( statement ) che esegue un compito o calcola un valore. Per usare una funzione, occorre definirla, all'interno dello scope dal quale la si invocherà.

- -

Vedi anche l'esaustivo capitolo della guida di riferimento, che tratta delle funzioni JavaScript, per avere maggiori dettagli.

- -

Definire una funzione

- -

Dichiarazioni di funzione

- -

Una definizione di funzione ( o dichiarazione di funzione, o istruzione di funzione ) consiste della parola chiave function, seguita da:

- - - -

Per esempio, il codice seguente definisce una funzione semplice chiamata square:

- -
function square(number) {
-  return number * number;
-}
-
- -

La funzione square riceve un argomento, chiamato number. La funzione contiene una sola istruzione che dice di restituire ( return ) l'argomento della funzione ( number ) moltiplicato per se stesso. L'istruzione return specifica il valore restituito dalla funzione.

- -
return number * number;
-
- -

I parametri primitivi ( quale un numero ) vengono passati alla funzione come valore; il valore è passato alla funzione, ma se la funzione cambia il valore del parametro, questo cambiamento non si riflette globalmente, o nella funzione chiamante ( la funzione che, eventualmente, ha invocato la funzione in esecuzione ).

- -

Se, invece, alla funzione viene passato un oggetto ( un valore non-primitivo, come, ad esempio, un Array oppure un oggetto definito dall'utente ) come parametro e la funzione modifica le proprietà dell'oggetto, quella modifica sarà visibile anche fuori dalla funzione, come si può vedere dal seguente esempio:

- -
function myFunc(theObject) {
-  theObject.make = "Toyota";
-}
-
-var mycar = {make: "Honda", model: "Accord", year: 1998};
-var x, y;
-
-x = mycar.make; // x gets the value "Honda"
-
-myFunc(mycar);
-y = mycar.make; // y gets the value "Toyota"
-                // (the make property was changed by the function)
-
- -

Espressioni di funzione

- -

Mentre la dichiarazione di funzione di cui sopra è, da un punto di vista sintattico, un'istruzione, le funzioni possono anche essere create da un'espressione di funzione. Una funzione di questo tipo può anche essere anonima; vale a dire, non deve avere un nome. Per esempio, la funzione square potrebbe essere stata definita come:

- -
var square = function(number) { return number * number };
-var x = square(4) // x gets the value 16
- -

Tuttavia, è possibile assegnare un nome alla funzione anche con l'espressione di funzione e quel nome potrà essere utilizzato all'interno della funzione, per riferirsi alla funzione stessa, oppure in un debugger, per identificare la funzione all'interno dello stack:

- -
var factorial = function fac(n) { return n<2 ? 1 : n*fac(n-1) };
-
-console.log(factorial(3));
-
- -

NB: l'oggetto console non è un oggetto standard. Non usatelo in un sito web, poichè potrebbe non funzionare correttamente. Per verificare il funzionamento dell'esempio precedente, usate, piuttosto:

- -

           window.alert(factorial(3));

- -

Le espressioni di funzione sono utili quando si vuole passare una funzione ad un'altra funzione, come argomento. Il prossimo esempio mostra una funzione map che viene definita e poi invocata, con una funzione anonima come primo parametro:

- -
function map(f,a) {
-  var result = [], // Create a new Array
-      i;
-  for (i = 0; i != a.length; i++)
-    result[i] = f(a[i]);
-  return result;
-}
-
- -

Il seguente codice:

- -
map(function(x) {return x * x * x}, [0, 1, 2, 5, 10]);
-
- -

restituisce [0, 1, 8, 125, 1000].

- -

In JavaScript, una funzione può essere definita in base ad una condizione. Per esempio, la definizione di funzione seguente definisce la funzione myFunc solo se num è uguale a 0 ( zero ):

- -
var myFunc;
-if (num == 0){
-  myFunc = function(theObject) {
-    theObject.make = "Toyota"
-  }
-}
- -

Per definire una funzione, inoltre, è possibile usare il costruttore Function, per creare funzioni da una stringa, in runtime, in modo simile a eval().

- -

Un metodo è una funzione che è una proprietà di un oggetto. Leggi di più sugli oggetti e sui metodi in Working with objects.

- -

Chiamare ( invocare ) una funzione

- -

Definire una funzione non significa eseguirla. Definire una funzione significa semplicemente darle un nome e specificare cosa fare quando la funzione viene chiamata ( invocata ). Chiamare una funzione significa eseguire le azioni specificate, utilizzando i parametri indicati. Per esempio, se definiamo la funzione square, possiamo chiamarla o invocarla nel modo seguente:

- -
square(5);
-
- -

Questa istruzione chiama la funzione, inviandole un argomento, il numero 5. La funzione esegue le sue istruzioni e restituisce il valore 25.

- -

Le funzioni devono essere in scope quando vengono chiamate, ma la dichiarazione di funzione può anche apparire sotto la chiamata, nel codice sorgente, come nell'esempio seguente:

- -
console.log(square(5));
-/* ... */
-function square(n) { return n*n }
-
- -

Lo scope di una funzione è la funzione nella quale è stata dichiarata, oppure l'intero programma se la dichiarazione è stata fatta al livello più alto, non annidata in alcun altro blocco di programmazione.

- -
-

Nota: l'ultimo esempio funziona solo quando la funzione viene definita utilizzando la sintassi usata nell'esempio ( function funcName(){} ). Il codice seguente, invece, non funzionerà:

-
- -
console.log(square(5));
-square = function (n) {
-  return n * n;
-}
-
- -

Gli argomenti di una funzione non sono limitati alle stringhe testuali e ai numeri. È possibile passare anche interi oggetti ad una funzione. La funzione show_props() (definita in Working with objects) è un esempio di funzione che riceve, come argomento, un oggetto.

- -

Una funzione può chiamare se stessa. Per esempio, ecco una funzione che calcola in modo ricorsivo i fattoriali ( molto simile alla funzione fac() vista poco prima in questa stessa pagina ):

- -
function factorial(n){
-  if ((n == 0) || (n == 1))
-    return 1;
-  else
-    return (n * factorial(n - 1));
-}
-
- -

A questo punto, è possibile calcolare i fattoriali dei cinque numeri seguenti:

- -
var a, b, c, d, e;
-a = factorial(1); // a gets the value 1
-b = factorial(2); // b gets the value 2
-c = factorial(3); // c gets the value 6
-d = factorial(4); // d gets the value 24
-e = factorial(5); // e gets the value 120
-
- -

Esistono altri metodi per chiamare una funzione. Ci sono casi in cui una funzione deve essere chiamata dinamicamente, oppure casi in cui il numero degli argomenti passati alla funzione varia, oppure casi in cui il contesto della chiamata di funzione deve essere impostato ad uno specifico oggetto, determinato in runtime ( tempo di esecuzione ). È chiaro che le funzioni sono, esse stesse, oggetti, e che questi oggetti hanno propri metodi (vedi l'oggetto Function). Uno di questi metodi, apply(), può essere usato a questo scopo.

- -

Lo scope di una funzione

- -

Alle variabili definite all'interno di una funzione non è possibile accedere dall'esterno della funzione, poichè la variabile è definita solo per lo scope della funzione ( scope: portata, ambiente, ambito in cui il nome della variabile può essere utilizzato per riferirsi ad essa ). Tuttavia, una funzione può accedere a tutte le variabili e a tutte le funzioni definite all'interno dello scope in cui è stata definita. In altre parole, una funzione definita nello scope globale può accedere a tutte le variabili definite nello scope globale. Una funzione definita all'interno di un'altra funzione può accedere anche a tutte le variabili definite nella funzione genitrice ( parent ), oltre che a tutte le altre variabili alle quali può accedere la funzione genitrice.

- -
// Queste variabili sono definite nello scope globale
-
-var num1 = 20,
-    num2 = 3,
-    name = "Chamahk";
-
-// Questa funzione è definita nello scope globale
-
-function multiply() {
-    return num1 * num2;
-    }
-
-multiply(); // restituisce 60
-
-// Un esempio di funzione annidata
-function getScore () {
-  var num1 = 2,
-      num2 = 3;
-
-  function add() {
-    return name + " scored " + (num1 + num2);
-  }
-
-  return add();
-}
-
-getScore(); // restituisce "Chamahk scored 5"
-
- -

Scope e lo stack della funzione

- -

Ricorsione

- -

Una funzione può chiamare se stessa. Esistono tre modi per una funzione di chiamare se stessa:

- -
    -
  1. il nome della funzione
  2. -
  3. arguments.callee
  4. -
  5. una variabile in-scope che fa da riferimento alla funzione
  6. -
- -

Per esempio, considerate la seguente definizione di funzione:

- -
var foo = function bar() {
-   // statements go here
-};
-
- -

All'interno del corpo della funzione, le tre seguenti istruzioni sono equivalenti:

- -
    -
  1. bar()
  2. -
  3. arguments.callee()
  4. -
  5. foo()
  6. -
- -

Una funzione che chiama se stessa viene detta funzione ricorsiva. In qualche modo, la ricorsione è analoga ad un loop. Entrambi eseguono lo stesso codice più volte ed entrambi richiedono una condizione (per evitare un loop infinito, o piuttosto, una ricorsione infinita, in questo caso). Per esempio, il loop seguente:

- -
var x = 0;
-while (x < 10) { // "x < 10" is the loop condition
-   // do stuff
-   x++;
-}
-
- -

può essere convertito in una funzione ricorsiva e in una chiamata a quella funzione:

- -
function loop(x) {
-  if (x >= 10) // "x >= 10" is the exit condition (equivalent to "!(x < 10)")
-    return;
-  // do stuff
-  loop(x + 1); // the recursive call
-}
-loop(0);
-
- -

Tuttavia, alcuni algoritmi non possono essere semplici loop iterativi. Per esempio, per avere tutti i nodi di una struttura ad albero (per esempio, il DOM) è molto più semplice usare la ricorsione:

- -
function walkTree(node) {
-  if (node == null) //
-    return;
-  // do something with node
-  for (var i = 0; i < node.childNodes.length; i++) {
-    walkTree(node.childNodes[i]);
-  }
-}
-
- -

Paragonato alla funzione loop, ciascuna chiamata ricorsiva, qui, esegue, a sua volta, molte chiamate ricorsive.

- -

È possibile convertire qualsiasi algoritmo ricorsivo in un algoritmo non ricorsivo, ma spesso la logica è molto più complessa e per farlo è necessario utilizzare uno stack. In effetti, la ricorsione stessa usa uno stack: lo stack della funzione.

- -

Un comportamento paragonabile allo stack può essere visto nell'esempio seguente:

- -
function foo(i) {
-  if (i < 0)
-    return;
-  console.log('begin:' + i);
-  foo(i - 1);
-  console.log('end:' + i);
-}
-foo(3);
-
-// Output:
-
-// begin:3
-// begin:2
-// begin:1
-// begin:0
-// end:0
-// end:1
-// end:2
-// end:3
- -

Funzioni annidate e chiusure

- -

È possibile annidare una funzione all'interno di una funzione. La funzione annidata ( interna ) è privata, rispetto alla funzione che la contiene (outer o esterna). Essa forma anche una chiusura ( closure ). Una chiusura è un'espressione (normalmente, una funzione) che può avere variabili libere ( non locali ) legate ad un ambiente (ambiente che "chiude" l'espressione).

- -

Dal momento in cui una funzione annidata è una chiusura, una funzione annidata può "ereditare" gli argomenti e le variabili della sua funzione contenitore (esterna o genitrice). In altre parole, la funzione interna contiene lo scope ( ambiente ) della funzione esterna.

- -

Per riepilogare:

- - - - - -

Ecco un esempio di funzione annidata:

- -
function addSquares(a,b) {
-  function square(x) {
-    return x * x;
-  }
-  return square(a) + square(b);
-}
-a = addSquares(2,3); // restituisce 13
-b = addSquares(3,4); // restituisce 25
-c = addSquares(4,5); // restituisce 41
-
- -

Dal momento in cui la funzione interna forma una chiusura, è possibile chiamare la funzione esterna e specificare gli argomenti per entrambe le funzioni, quella esterna e quella interna:

- -
function outside(x) {
-  function inside(y) {
-    return x + y;
-  }
-  return inside;
-}
-fn_inside = outside(3); // Come dire: dammi una funzione che addizioni 3 a qualsiasi altro valore le venga passato
-result = fn_inside(5); // restituisce 8
-
-result1 = outside(3)(5); // restituisce 8
-
- -

Persistenza delle variabili

- -

Da notare come x venga preservata anche all'uscita da inside. Una chiusura deve preservare argomenti e variabili in tutti gli scope ai quali è riferita. Poichè ogni chiamata potrebbe trasportare argomenti differenti, per ogni chiamata alla funzione outside viene creata una nuova chiusura. La memoria può essere liberata solo quando inside non è più accessibile.

- -

Una chiusura non è differente da un riferimento ad un oggetto, ma è meno ovvia di quest'ultimo, perchè non richiede di impostare direttamente il riferimento e perchè non è possibile ispezionare l'oggetto al quale il riferimento punta.

- -

Funzioni annidate multiple

- -

Le funzioni possono essere annidate a più livelli. Per esempio, una funzione (A), può contenere una funzione (B), che può contenere, a sua volta, una funzione (C). Entrambe le funzioni B e C formano una chiusura, qui, così B può accedere ad A e C può accedere a B. Inoltre, visto che C può accedere a B che può accedere ad A, C può anche accedere ad A. Quindi, le chiusure possono contenere più scope; ciascuna chiusura contiene lo scope delle funzioni che la contengono. Questo meccanismo è chiamato scope chaining ( catena di scope ). (Perchè è chiamata "catena" sarà chiaro tra poco.)

- -

Considerate l'esempio seguente:

- -
function A(x) {
-  function B(y) {
-    function C(z) {
-      console.log(x + y + z);
-    }
-    C(3);
-  }
-  B(2);
-}
-A(1); // logs 6 (1 + 2 + 3)
-
- -

In questo esempio, C accede alla variabile y di B e alla x di A. Questo accade perchè:

- -
    -
  1. B forma una chiusura che include A: quindi, B può accedere agli argomenti ed alle variabili di A.
  2. -
  3. C forma una chiusura che include B.
  4. -
  5. Poichè la chiusura di B include A, la chiusura di C include A; C può accedere agli argomenti ed alle variabili sia di B che di A. In altre parole, C unisce in una catena gli scope di B ed A in quell'ordine.
  6. -
- -

Il contrario, tuttavia, non è vero. A non può accedere a C, perchè A non può accedere ad alcun argomento o variabile di B, di cui C è una variabile. Quindi, C resta privata solo a  B.

- -

Conflitti tra nomi

- -

Quando due argomenti o variabili, all'interno degli scope di una chiusura hanno lo stesso nome, nasce un conflitto tra nomi. Gli scope più interni hanno la precedenza, così lo scope più annidato ha la precedenza più elevata, mentre lo scope più esterno ha la precedenza più bassa. Questa è la catena degli scope. Il primo della catena è lo scope più annidato, mentre l'ultimo è lo scope più esterno. Vediamo il seguente esempio:

- -
function outside() {
-  var x = 10;
-  function inside(x) {
-    return x;
-  }
-  return inside;
-}
-result = outside()(20); // returns 20 instead of 10
- -

Il conflitto tra nomi avviene con l'istruzione return x ed è tra il nome del parametro x di inside ed il nome della variabile x di outside. La catena di scope qui è {inside, outside, global object}. Quindi, la x di inside ha la precedenza sulla x di outside: il valore restituito, alla fine, sarà 20 ( la x di inside ) e non 10 ( la x di  outside ).

- -

Closure

- -

Le closure sono uno dei meccanismi più potenti di JavaScript. JavaScript permette l'annidamento di funzioni e riconosce alla funzione interna il pieno accesso a tutte le variabili e a tutte le funzioni definite nella funzione esterna ( e a tutte le altre variabili e funzioni cui la funzione esterna ha accesso ). Tuttavia, la funzione esterna non ha accesso alle variabili ed alle funzioni definite nella funzione interna. Questo offre una certa protezione alle variabili della funzione interna. Inoltre, dal momento in cui la funzione interna ha accesso allo scope della funzione esterna, le variabili e le funzioni definite nella funzione esterna sopravviveranno alla funzione esterna stessa, se la funzione interna fa in modo di sopravvivere alla funzione esterna. Una closure viene creata quando la funzione interna viene resa disponibile in qualche modo agli scope esterni alla funzione esterna.

- -
var pet = function(name) {   // La funzione esterna definisce una variabile di nome "name"
-  var getName = function() {
-    return name;             // La funzione interna ha accesso alla variabile "name" della funzione esterna
-  }
-  return getName;            // restituisce la funzione interna, esponendola, quindi, a scope esterni
-},
-myPet = pet("Vivie");
-
-myPet();                     // restituisce "Vivie"
-
- -

Può essere molto più complicato del codice scritto sopra. Può essere restituito un oggetto contenente metodi per manipolare le variabili interne della funzione esterna.

- -
var createPet = function(name) {
-  var sex;
-
-  return {
-    setName: function(newName) {
-      name = newName;
-    },
-
-    getName: function() {
-      return name;
-    },
-
-    getSex: function() {
-      return sex;
-    },
-
-    setSex: function(newSex) {
-      if(typeof newSex == "string" && (newSex.toLowerCase() == "male" || newSex.toLowerCase() == "female")) {
-        sex = newSex;
-      }
-    }
-  }
-}
-
-var pet = createPet("Vivie");
-pet.getName();                  // Vivie
-
-pet.setName("Oliver");
-pet.setSex("male");
-pet.getSex();                   // male
-pet.getName();                  // Oliver
-
- -

Nel codice sopra, la variabile name della funzione esterna è accessibile alle funzioni interne e non c'è modo di accedere alle variabili interne, se non attraverso le funzioni interne. Le variabili interne della funzione interna agiscono come magazzino sicuro per le funzioni interne. Esse conservano i dati "persistenti" e sicuri che le funzioni interne utilizzano. Le funzioni non hanno nemmeno bisogno di vedersi assegnare ad una variabile o di avere un nome.

- -
var getCode = (function(){
-  var secureCode = "0]Eal(eh&2";    // A code we do not want outsiders to be able to modify...
-
-  return function () {
-    return secureCode;
-  };
-})();
-
-getCode();    // Returns the secureCode
-
- -

Ci sono, tuttavia, alcuni pericoli dai quali guardarsi, quando si utilizzano le closure. Se una funzione chiusa definisce una variabile che ha lo stesso nome di una variabile definita nello scope esterno, non sarà più possibile riferirsi alla variabile esterna.

- -
var createPet = function(name) {  // Outer function defines a variable called "name"
-  return {
-    setName: function(name) {    // Enclosed function also defines a variable called "name"
-      name = name;               // ??? How do we access the "name" defined by the outer function ???
-    }
-  }
-}
-
- -

È davvero  complicato usare la variabile magica this nelle closure. La variabile this è da usarsi con cautela, poichè ciò a cui this si riferisce dipende esclusivamente da dove è stata invocata la funzione, piuttosto che da dove è stata definita.

- -

Usare l'oggetto arguments

- -

Gli argomenti di una funzione vengono memorizzati in un oggetto, strutturato come un array. All'interno di una funzione, è possibile riferirsi agli argomenti passati alla funzione stessa nel modo seguente:

- -
arguments[i]
-
- -

dove i è il numero ordinale dell'argomento, a partire da zero. Così, il primo argomento passato ad una funzione sarà arguments[0]. Il numero totale degli argomenti è dato da arguments.length.

- -

Usando l'oggetto arguments, è possibile chiamare una funzione con più argomenti di quanti ne possa formalmente accettare. Questo è spesso utile se non si sa in anticipo quanti argomenti verranno passati alla funzione. Si può usare l'attributo  arguments.length per determinare il numero degli argomenti realmente passati alla funzione, per poi accedere a ciascuno di essi usando l'oggetto arguments.

- -

Prendiamo, per esempio, una funzione che unisca più stringhe. Il solo argomento formale previsto per la funzione è una stringa che specifica i caratteri da usare per separare le singole voci. La funzione viene definita così:

- -
function myConcat(separator) {
-   var result = "", // initialize list
-       i;
-   // iterate through arguments
-   for (i = 1; i < arguments.length; i++) {
-      result += arguments[i] + separator;
-   }
-   return result;
-}
-
- -

È possibile passare una quantità qualsiasi di argomenti alla funzione e la funzione comporrà una stringa testuale contenente tutti gli argomenti passati:

- -
// returns "red, orange, blue, "
-myConcat(", ", "red", "orange", "blue");
-
-// returns "elephant; giraffe; lion; cheetah; "
-myConcat("; ", "elephant", "giraffe", "lion", "cheetah");
-
-// returns "sage. basil. oregano. pepper. parsley. "
-myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley");
-
- -
-

Nota: La variabile arguments è simile ad un array (  "array-like" ), ma non è un array. È simile ad un array poichè ha un indice numerato ed una proprietà length. Tuttavia, non possiede tutti i metodi di manipolazione degli array.

-
- -

Vedi l'oggetto Function nella JavaScript reference, per avere maggiori informazioni.

- -

I parametri di una funzione

- -

A partire da ECMAScript 6, esistono due nuovi tipi di parametri: i parametri di default e i parametri rest.

- -

I parametri di default

- -

In JavaScript, i parametri di una funzione hanno come valore di default undefined. Tuttavia, in alcune situazioni potrebbe essere utile impostare un diverso valore di default. In questo, possono aiutare i parametri di default.

- -

In passato, la strategia comune per impostare i valori di default era quella di verificare i valori dei parametri, all'interno del corpo della funzione, ed assegnare loro un valore, nel caso fossero stati undefined. Se nell'esempio seguente non venisse passato, durante la chiamata, alcun valore per b, il suo valore sarebbe undefined, anche quando venisse valutata l'istruzione a*b, e la chiamata a multiply restituirebbe NaN ( Not a Number ). Tuttavia, questo valore viene definito nella seconda riga:

- -
function multiply(a, b) {
-  b = typeof b !== 'undefined' ?  b : 1;
-
-  return a*b;
-}
-
-multiply(5); // 5
-
- -

Con i parametri di deafult, la verifica all'interno del corpo della funzione non è più necessaria. Ora, è possibile mettere 1 come valore di default per b nella dichiarazione della funzione:

- -
function multiply(a, b = 1) {
-  return a*b;
-}
-
-multiply(5); // 5
- -

Per maggiori dettagli, vedi paremetri di default nella Javascript reference.

- -

I parametri Rest

- -

La sintassi dei rest parameter permette di rappresentare un indefinito numero di argomenti come un array. Nell'esempio, usiamo i parametri rest per rappresentare l'insieme degli argomenti composto dagli argomenti successivi al primo ( a partire dal secondo argomento fino alla fine ). Poi, moltiplichiamo ciascun argomento dell'insieme per il primo. Questo esempio utilizza una funzione a freccia, che verrà introdotta nella prossima sezione.

- -
function multiply(multiplier, ...theArgs) {
-  return theArgs.map(x => multiplier * x);
-}
-
-var arr = multiply(2, 1, 2, 3);
-console.log(arr); // [2, 4, 6]
- -

Le funzioni a freccia

- -

Una espressione di funzione a freccia ( nota anche come fat arrow function ) ha una sintassi più stringata rispetto alle espressioni di funzione e forza, lessicalmente, il valore di this. Le funzioni a freccia sono sempre anonime. Vedi anche il post di hacks.mozilla.org: "ES6 In Depth: Arrow functions".

- -

Sono due i fattori che influenzarono l'introduzione delle funzioni a freccia: la brevità delle funzioni ed il this lessicale.

- -

Funzioni più brevi

- -

In alcuni modelli funzionali, funzioni più brevi sono le benvenute. Paragoniamo le due istruzioni seguenti:

- -
var a = [
-  "Hydrogen",
-  "Helium",
-  "Lithium",
-  "Beryl­lium"
-];
-
-var a2 = a.map(function(s){ return s.length });
-var a3 = a.map( s => s.length );
- -

Il this lessicale

- -

Until arrow functions, every new function defined its own this value (a new object in case of a constructor, undefined in strict mode function calls, the context object if the function is called as an "object method", etc.). This proved to be annoying with an object-oriented style of programming.

- -
function Person() {
-  // The Person() constructor defines `this` as itself.
-  this.age = 0;
-
-  setInterval(function growUp() {
-    // In nonstrict mode, the growUp() function defines `this`
-    // as the global object, which is different from the `this`
-    // defined by the Person() constructor.
-    this.age++;
-  }, 1000);
-}
-
-var p = new Person();
- -

In ECMAScript 3/5, this issue was fixed by assigning the value in this to a variable that could be closed over.

- -
function Person() {
-  var self = this; // Some choose `that` instead of `self`.
-                   // Choose one and be consistent.
-  self.age = 0;
-
-  setInterval(function growUp() {
-    // The callback refers to the `self` variable of which
-    // the value is the expected object.
-    self.age++;
-  }, 1000);
-}
- -

Alternatively, a bound function could be created so that the proper this value would be passed to the growUp() function.

- -

Arrow functions capture the this value of the enclosing context, so the following code works as expected.

- -
function Person(){
-  this.age = 0;
-
-  setInterval(() => {
-    this.age++; // |this| properly refers to the person object
-  }, 1000);
-}
-
-var p = new Person();
- -

Predefined functions

- -

JavaScript has several top-level, built-in functions:

- -
-
{{jsxref("Global_Objects/eval", "eval()")}}
-
-

The eval() method evaluates JavaScript code represented as a string.

-
-
{{jsxref("Global_Objects/uneval", "uneval()")}} {{non-standard_inline}}
-
-

The uneval() method creates a string representation of the source code of an {{jsxref("Object")}}.

-
-
{{jsxref("Global_Objects/isFinite", "isFinite()")}}
-
-

The global isFinite() function determines whether the passed value is a finite number. If needed, the parameter is first converted to a number.

-
-
{{jsxref("Global_Objects/isNaN", "isNaN()")}}
-
-

The isNaN() function determines whether a value is {{jsxref("Global_Objects/NaN", "NaN")}} or not. Note: coercion inside the isNaN function has interesting rules; you may alternatively want to use {{jsxref("Number.isNaN()")}}, as defined in ECMAScript 6, or you can use typeof to determine if the value is Not-A-Number.

-
-
{{jsxref("Global_Objects/parseFloat", "parseFloat()")}}
-
-

The parseFloat() function parses a string argument and returns a floating point number.

-
-
{{jsxref("Global_Objects/parseInt", "parseInt()")}}
-
-

The parseInt() function parses a string argument and returns an integer of the specified radix (the base in mathematical numeral systems).

-
-
{{jsxref("Global_Objects/decodeURI", "decodeURI()")}}
-
-

The decodeURI() function decodes a Uniform Resource Identifier (URI) previously created by {{jsxref("Global_Objects/encodeURI", "encodeURI")}} or by a similar routine.

-
-
{{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent()")}}
-
-

The decodeURIComponent() method decodes a Uniform Resource Identifier (URI) component previously created by {{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}} or by a similar routine.

-
-
{{jsxref("Global_Objects/encodeURI", "encodeURI()")}}
-
-

The encodeURI() method encodes a Uniform Resource Identifier (URI) by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character (will only be four escape sequences for characters composed of two "surrogate" characters).

-
-
{{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent()")}}
-
-

The encodeURIComponent() method encodes a Uniform Resource Identifier (URI) component by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character (will only be four escape sequences for characters composed of two "surrogate" characters).

-
-
{{jsxref("Global_Objects/escape", "escape()")}} {{deprecated_inline}}
-
-

The deprecated escape() method computes a new string in which certain characters have been replaced by a hexadecimal escape sequence. Use {{jsxref("Global_Objects/encodeURI", "encodeURI")}} or {{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}} instead.

-
-
{{jsxref("Global_Objects/unescape", "unescape()")}} {{deprecated_inline}}
-
-

The deprecated unescape() method computes a new string in which hexadecimal escape sequences are replaced with the character that it represents. The escape sequences might be introduced by a function like {{jsxref("Global_Objects/escape", "escape")}}. Because unescape() is deprecated, use {{jsxref("Global_Objects/decodeURI", "decodeURI()")}} or {{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent")}} instead.

-
-
- -

{{PreviousNext("Web/JavaScript/Guide/Loops_and_iteration", "Web/JavaScript/Guide/Expressions_and_Operators")}}

diff --git a/files/it/web/javascript/guida/grammar_and_types/index.html b/files/it/web/javascript/guida/grammar_and_types/index.html deleted file mode 100644 index 2a43d5230d..0000000000 --- a/files/it/web/javascript/guida/grammar_and_types/index.html +++ /dev/null @@ -1,659 +0,0 @@ ---- -title: Grammatica e tipi -slug: Web/JavaScript/Guida/Grammar_and_types -translation_of: Web/JavaScript/Guide/Grammar_and_types ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Introduction", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}
- -

Questo capitolo tratta la sintassi di base di JavaScript, le dichiarazioni di variabili, i tipi di dati e i letterali.

- -

Nozioni di base

- -

JavaScript mutua molta della sua sintassi da Java, ma è anche influenzato da Awk, Perl e Python.

- -

JavaScript è sensibile al maiuscolo-minuscolo (case-sensitive) e usa l'insieme di caratteri Unicode.

- -

In JavaScript, le istruzioni sono separate da punto e vigola (;). Spazi, tabulazioni e caratteri di a capo sono chiamati spazi bianchi. Il testo sorgente di uno script JavaScript viene analizzato da sinistra verso destra ed è convertito in una sequenza di elementi di input che sono: token, caratteri di controllo, terminatori di linea, commenti o spazi bianchi. ECMAScript definisce anche determinate parole chiave e letterali e ha delle regole per l'inserimento automatico dei punti e virgola (ASI) per chiudere le istruzioni. Tuttavia si raccomanda di aggiungere sempre un punto e virgola per terminare ogni istruzione, questo eviterà effetti collaterali. Per maggiori informazioni si veda il riferimento dettagliato riguardo la lexical grammar di JavaScript.

- -

Commenti

- -

La sintassi dei commenti è la stessa di quelli del C++ e di molti altri linguaggi:

- -
// una linea di commento
-
-/* questo è un commento più lungo,
-   occupa più linee
- */
-
-/* Però non puoi /* annidare i commenti */ SyntaxError */
- -

Dichiarazioni

- -

Ci sono tre tipi di dichiarazioni in JavaScript.

- -
-
{{jsxref("Statements/var", "var")}}
-
Dichiarazione di una variabile, opzionalmente inizializzata ad un valore.
-
{{experimental_inline}} {{jsxref("Statements/let", "let")}}
-
Dichiarazione di una variabile locale con visibilità nel blocco, opzionalmente inizializzata ad un valore.
-
{{experimental_inline}} {{jsxref("Statements/const", "const")}}
-
Dichiarazione di una costante in sola lettura con un nome.
-
- -

Variabili

- -

Le variabili sono nomi simbolici da usare nelle applicazioni in luogo dei valori che rappresentano. I nomi delle variabili, chiamati  {{Glossary("Identifier", "identificatori")}}, devono seguire certe regole di scrittura.

- -

Un identificatore JavaScript deve iniziare con una lettera, un trattino basso (_) o segno del dollaro ($), mentre i caratteri successivi possono anche essere le cifre (0-9). Siccome JavaScript è case-sensitive, le lettere includono i caratteri da "A" fino a "Z" (maiuscoli) e i caratteri da "a" fino a "z" (minuscoli).

- -

Si possono usare anche le lettere ISO 8859-1 o Unicode come per esempio å e ü negli identificatori. Possono essere usate anche le sequenze di escape di Unicode come caratteri negli identificatori.

- -

Alcuni esempi di nomi leciti sono Number_hits, temp99 e _name.

- -

Dichiarazione di variabili

- -

Una variabile può essere dichiarata in tre modi:

- - - -

Valutazione delle variabili

- -

Una variabile dichiarata usando le istruzioni  var o let senza nessun valore iniziale specificato ha il valore {{jsxref("undefined")}}.

- -

Il tentativo di accedere ad una variabile non dichiarata o di accedere ad un identificatore dichiarato con l'istruzione let, prima di una sua inizializzazione, provocherà un'eccezione di {{jsxref("ReferenceError")}}:

- -
var a;
-console.log("Il valore di a è " + a); // Scrive nel log "Il valore di a è undefined"
-
-console.log("Il valore di b è " + b); // Solleva una eccezione ReferenceError
-
-console.log("Il valore di c è " + c); // Scrive nel log "Il valore di c è undefined" 
-var c;
-
-console.log("Il valore di x è " + x); // Solleva una eccezione ReferenceError: x is not defined
-let x;
- -

Si può usare undefined per determinare se una variabile ha un valore oppure no. Nel codice seguente alla variabile input non è stato assegnato un valore e la condizione dell'istruzione if è

- -

valuta a true.

- -
var input;
-if(input === undefined){
-  faiQuesto();
-} else {
-  faiQuello();
-}
-
- -

Il valore undefined si comporta come false quando viene usato in un contesto booleano. Ad esempio il codice seguente esegue la funzione miaFunzione perché l'elemento di mioArray non è definito:

- -
var mioArray = [];
-if (!mioArray[0]) miaFunzione();
-
- -

Il valore undefined viene convertito in NaN quando viene usato in un contesto numerico.

- -
var a;
-a + 2;  // Viene valutato a NaN
- -

Quando viene valutata una variabile {{jsxref("null")}}, il valore null si comporta come 0 in un contesto numerico e false in un contesto booleano. Per esempio:

- -
var n = null;
-console.log(n * 32); // Visualizzera nella console 0
-
- -

Visibilità delle variabili

- -

Quando una variabile viene dichiarata fuori da una qualsiasi funzione viene chiamata variabile globale, poiché è disponibile  in tutto il codice nel documento corrente. Quando invece la variabile viene dichiarata in una funzione viene chiamata variabile locale, perché è disponibile soltanto all'interno di quella funzione.

- -

JavaScript prima di ECMAScript 2015 non aveva una visibilità a livello di blocco; piuttosto una variabile dichiarata all'interno di un blocco era locale alla funzione (o al contesto globale) in cui il blocco risiedeva. Per esempio il seguente codice scriverà nel log 5, perché la visibilità di x è la funzione (o il contesto globale) all'interno del quale x viene dichiarata e non il blocco, che in questo caso è l'istruzione if.

- -
if (true) {
-  var x = 5;
-}
-console.log(x);  // 5
-
- -

Il comportamento cambia quando si usa l'istruzione let introdotta in ECMAScript 2015.

- -
if (true) {
-  let y = 5;
-}
-console.log(y);  // ReferenceError: y non è definita
-
- -

Sollevamento delle variabili

- -

Un'altra cosa inusuale riguardo le variabili in JavaScript è che si può fare riferimento ad una variabile dichiarata più avanti nello script senza causare una eccezione. Questo concetto è conosciuto come innalzamento (hoisting); le variabili in JavaScript sono in un certo senso "sollevate" o spostate all'inizio della definizione del corpo della funzione o dell'istruzione. Tuttavia le variabili che sono state sollevate ritornano il valore undefined. Dunque se viene usata (o si fa riferimento ad) una variabile prima che venga dichiarata questa ritornà undefined.

- -
/**
- * Esempio 1
- */
-console.log(x === undefined); // visualizza "true" nel log
-var x = 3;
-
-/**
- * Esempio 2
- */
-var myvar = "mio valore";
-
-(function() {
-  console.log(myvar); // visualizza "undefined" nel log
-  var myvar = "valore locale";
-})();
-
- -

L'esempio sopra sarà interpretato nello stesso modo di:

- -
/**
- * Esempio 1
- */
-var x;
-console.log(x === undefined); // visualizza nel log "true"
-x = 3;
-
-/**
- * Esempio 2
- */
-var myvar = "mio valore";
-
-(function() {
-  var myvar;
-  console.log(myvar); // undefined
-  myvar = "valore locale";
-})();
-
- -

Per via dell'innalzamento, tutte le istruzioni var in una funzione dovrebbero essere posizionate prima di ogni altra istruzione che vada a definire una funzione. Questa buona pratica incrementa la chiarezza del codice.

- -

In ECMAScript 2015, let (const) non solleverà/sposterà la variabile all'inizio della dichiarazione del blocco, dunque un riferimento alla variabile nel blocco prima che questa venga dichiarata risulterà in un'eccezione di {{jsxref("ReferenceError")}}. La variabile si dice in una "zona temporale morta" ("temporal dead zone") dall'inizio del blocco fino alla a che non si incontri la sua dichiarazione.

- -
console.log(x); // Solleverà un'eccezione ReferenceError
-let x = 3
- -

Sollevamento delle Funzioni

- -

Nel caso delle funzioni, solo la dichiarazione della funzione verrà spostata all'inizio. Se la funzione viene introdotta da un'espressione, in questo caso non verrà spostata.

- -
/* Function declaration */
-
-foo(); // "bar"
-
-function foo() {
-  console.log("bar");
-}
-
-
-/* Function expression */
-
-baz(); // TypeError: baz is not a function
-
-var baz = function() {
-  console.log("bar2");
-};
- -

Variabli globali

- -

Le variabili globali sono in effetti proprietà dell'oggetto globale. Nelle pagine web l'oggetto globale è {{domxref("window")}} quindi è possibile impostare e accedere alle variabili globali usando la sintassi window.variabile.

- -

Di conseguenza è possibile accedere a variabili globali dichiarate in una finestra o un frame da un'altra finestra o frame specificando il nome della finestra o del frame. Per esempio, se una variabile chiamata numeroDiTelefono è dichiarata in un documento, è possibile far riferimento a questa variabile dall'interno di un iframe come parent.numeroDiTelefono.

- -

Costanti

- -

È possibile creare una costante in sola lettura dandole un nome usando la parola chiave {{jsxref("Statements/const", "const")}}. La sintassi di un identificatore di costante è la stessa di un identificatore di variabile: deve iniziare con una lettera, trattino basso (_) o segno del dollaro ($) e può contenere caratteri alfabetici, numerici o trattini bassi.

- -
const PI = 3.14;
-
- -

Una costante non può cambiare il suo valore attraverso ulteriori assegnazioni o essere ridichiarata mentre lo script è in esecuzione. Deve anche essere inizializzata ad un valore.

- -

Le regole di visibilità per le costanti sono le stesse di quelle per le variabil con visibilità al livello di blocco dichiarate con l'istruzione let. Se la parola chiave const viene omessa si assume che l'identificatore rappresenta una variabile.

- -

Non è possibile dichiarare una costante con lo stesso nome di una funzione o di una variabile nello stesso spazio di visibilità. Per esempio:

- -
// QUESTO CAUSERÀ UN ERRORE
-function f() {};
-const f = 5;
-
-// ANCHE QUESTO CAUSERÀ UN ERRORE
-function f() {
-  const g = 5;
-  var g;
-
-  //istruzioni
-}
-
- -

Strutture dati e tipi

- -

Tipi di dato

- -

L'ultimo standard ECMAScript definisce sette tipi di dati:

- - - -

Sebbene questi tipi di dati siano relativamente pochi questi permettono di eseguire funzioni utili nelle applicazioni. {{jsxref("Object", "Objects")}} e {{jsxref("Function", "functions")}} sono altri elementi fondamentali nel linguaggio. Si può pensatre agli oggetti come a contenitori con un nome per dei valori e alle funzioni come a procedure che l'applicazione può compiere.

- -

Conversione dei tipi dei dati

- -

JavaScript è un linguaggio con tipi assegnati dinamicamente. Questo significa che non si va a specificare il tipo di dato che una variabile conterrà quando viene dichiarata e anche che il tipo di un dato viene convertito automaticamente a seconda delle necessità durante l'esecuzione dello script. Così, per esempio, si può definire una variabile come segue:

- -
var risposta = 42;
-
- -

E più avanti è possibile assegnare alla stessa variabile un valore testo (stringa), per esempio:

- -
risposta = "Grazie per tutti i pesci...";
-
- -

Poiché in JavaScript i tipi si assegnano dinamicamente questa assegnazione non causerà un messaggio di errore.

- -

Nelle espressioni che coinvolgono valori numerici e stringhe con l'operatore + JavaScript converte i valori numerici in stringhe. Per esempio si considerino le seguenti istruzioni:

- -
x = "La risposta è " + 42 // "La risposta è 42"
-y = 42 + " è la risposta" // "42 è la risposta"
-
- -

In istruzioni che coinvolgono altri operatori JavaScript non converte valori numerici in stringa. Per esempio:

- -
"37" - 7 // 30
-"37" + 7 // "377"
-
- -

Conversione delle stringhe in numeri

- -

Nel caso in cui il valore che rappresenta un numero è memorizzato come stringa ci sono dei metodi per eseguire la conversione:

- - - -

parseInt ritornerà soltanto numeri interi,  ha una utilità ridotta per i numeri decimali. In aggiunta è buona pratica nell'uso di parseInt includere il parametro base, questo parametro è usato per specificare quale sistema di numerazione deve essere usato.

- -

Un metodo alternativo per recuperare un numero da un testo è di usare l'operatore + (più unario):

- -
"1.1" + "1.1" = "1.11.1"
-(+"1.1") + (+"1.1") = 2.2
-// Note: le parentesi sono aggiunte per chiarezza, non sono richieste.
- -

Letterali

- -

I letterali sono usati per rappresentare i valori in JavaScript. Questi sono valori fissati, non variabili, che venvono letteralmente inseriti nello script. Questa sezione descrive i seguenti tipi di letterali:

- - - -

Letterali di array

- -

Un letterale di array è un elenco di zero o più espressioni ognuna delle quali rappresenta un elemento dell'array, inclusa in parentesi quadre ([]). Quando si crea un array usando un letterale l'array stesso viene inizializzato con i valori specificati come elementi, la sua lunghezza è impostata al numero di elementi specificati.

- -

Il seguente esempio crea un array tipiDiCaffe con tre elementi e una lunghezza di tre:

- -
var tipiDiCaffe = ["French Roast", "Colombian", "Kona"];
-
- -
-

Nota: Un letterale di array è un tipo di inizializzatore di oggetto. Vedi Usando inizializzatori di Oggetti.

-
- -

Se un array viene creato usando un letterale in uno script top-level, JavaScript interpreta l'array ogni volta che valuta l'espressione che contiene l'array letterale. In aggiunta l'array letterale usato in una funzione viene creato ogni volta che la funzione viene chiamata.

- -

Gli array letterali sono anche oggetti Array. Si veda {{jsxref("Array")}} e Collezione indicizzata per i dettagli sugli oggetti Array.

- -

Virgole aggiuntive negli array letterali

- -

Non è obbligatorio specificare tutti gli elementi in un array letterale. Mettendo due virgole in fila l'array viene creato con il valore undefined per gli elementi non specificati. Il seguente esempio crea l'array pesce:

- -
var pesce = ["Leone", , "Angelo"];
-
- -

Questo array ha due elementi con un valore e un elemento vuoto (pesce[0] is "Leone", pesce[1] è undefined, e pesce[2] è "Angelo").

- -

Inserendo una virgola in fondo alla lista degli elementi la virgola stessa verrà ignorata. Nel seguente esempio la lunghezza dell'array è tre, non c'è un miaLista[3]. Tutte le altre virgole nell'elenco indicano un elemento nuovo.

- -
-

Nota: Le virgole in coda possono creare errori nelle versioni più vecchie dei browser ed è buona pratica rimuoverle.

-
- -
var miaLista = ['casa', , 'scuola', ];
-
- -

Nel seguente esempio la lunghezza dell'array è quattro e miaLista[0] e mialista[2] sono mancanti.

- -
var miaLista = [ , 'casa', , 'scuola'];
-
- -

Nel seguente esempio la lunghezza dell'array è quattro e mialista[1] e miaLista[3] sono mancanti. Soltanto l'ultima virgola viene ignorata.

- -
var miaLista = ['casa', , 'scuola', , ];
-
- -

Comprendere il comportamento delle virgole in più è importante per comprendere JavaScript come linguaggio, in ogni caso nella scrittura del codice: è buona norma dichiarare esplicitamente gli elementi mancanti come undefined, questo migliorerà la chiarezza e la manutenibilità del codice.

- -

Letterali di booleani

- -

Il tipo Boolean ha due valori letterali: true e false.

- -

Non vanno confusi i valori primitivi Booleani true e false con i valori true e false dell'oggetto Boolean. L'oggetto Boolean è un involucro intorno al tipo primitivo Booleano. Vedi {{jsxref("Global_Objects/Boolean", "Boolean")}} per maggiori informazioni.

- -

Letterali di numeri Interi

- -

Gli interi possono essere rappresentati in decimale (base 10), esadecimale (base 16), ottale (base 8) e binario (base 2).

- - - -

Alcuni esempi i di letterali di interi sono:

- -
0, 117 and -345 (decimale, base 10)
-015, 0001 and -0o77 (ottale, base 8)
-0x1123, 0x00111 and -0xF1A7 (esadecimale, "hex" o base 16)
-0b11, 0b0011 and -0b11 (binario, base 2)
-
- -

Per maggiori informazioni, vedi Numeric literals in the Lexical grammar reference.

- -

Letterali di numeri in virgola-mobile

- -

Un letterale per un numero in virgola mobile può avere le seguenti parti:

- - - -

La parte esponente è una "e" o "E" seguita da un intero che può essere con segno (preceduto da "+" o "-"). Un numero in virgola mobile deve avere almeno una cifra e un punto oppure una "e" (o "E").

- -

Più concisamente la sintassi è:

- -
[(+|-)][cifre][.cifre][(E|e)[(+|-)]cifre]
-
- -

Per esempio:

- -
3.1415926
--.123456789
--3.1E+12
-.1e-23
-
- -

Letterali di oggetti

- -

Un letterale di un oggetto è una lista di zero o più coppie di nomi di proprietà e valori associati di un oggetto racchiusi in parentesi graffe ({}). Non andrebbe usato un letterale di un oggetto all'inizio di una istruzione, questo porterà ad un errore o non si comporterà come ci si aspetta perché { sarà interpretata come l'inizio di un blocco.

- -

Quello seguente è un esempio di un letterale di un oggetto. Il primo elemento dell'oggetto automobile definisce un proprietà, miaAutomobile, e gli assegna il testo "Saturn"; il secondo elemento, la proprietà getAutomobile, è immediatamente assegnata al valore risultante dall'invocazione della funzione (tipiDiAutomobile("Honda")); il terzo elemento, la proprietà speciale, usa una variabile esistente (saldi).

- -
var saldi = "Toyota";
-
-function tipiDiAutomobile(nome) {
-  if (nome === "Honda") {
-    return nome;
-  } else {
-    return "Spiacente, noi non vendiamo " + nome + ".";
-  }
-}
-
-var automobile = { miaAutomobile: "Saturn", getAutomobile: tipiDiAutomobile("Honda"), speciale: saldi };
-
-console.log(automobile.miaAutomobile);   // Saturn
-console.log(automobile.getAutomobile);  // Honda
-console.log(automobile.speciale); // Toyota
-
- -

In aggiunta si possono usare letterali di tipo numerico o testo come nome di una proprietà o annidare un oggetto dentro un altro. Il seguente esempio usa queste opzioni.

- -
var automobile = { molteAutomobili: {a: "Saab", "b": "Jeep"}, 7: "Mazda" };
-
-console.log(automobile.molteAutomobili.b); // Jeep
-console.log(automobile[7]); // Mazda
-
- -

I nomi delle proprietà degli oggetti possono essere un testo qualsiasi, incluso il testo vuoto. Se il nome della proprietà non è un {{Glossary("Identifier","identifier")}} JavaScript valido o un numero dovrà essere racchiuso tra virgolette. I nomi di proprietà che non sono identificatori validi non possono neanche essere acceduti usando il punto (.), potranno però essere acceduti e impostati usando la notazione analoga a quella degli array ("[]").

- -
var nomiDiProprietaInusuali = {
-  "": "Una stringa vuota",
-  "!": "Bang!"
-}
-console.log(nomiDiProprietaInusuali."");   // SyntaxError: Unexpected string
-console.log(nomiDiProprietaInusuali[""]);  // Una stringa vuota
-console.log(nomiDiProprietaInusuali.!);    // SyntaxError: Unexpected token !
-console.log(nomiDiProprietaInusuali["!"]); // Bang!
- -

In ES2015, i letterali di oggetti sono estesi per supportare l'impostazione del prototipo al momento della costruzione, forme abbreviate per le assegnazioni tipo foo: foo, definizioni di metodi, eseguire chiamate a super e calcolare il nome di proprietà con espressioni. Nel'insieme queste aggiunte avvicinano i letterali di oggetti e le dichiarazioni delle classi permettendo quindi di beneficiare di alcune delle stesse comodità della progettazione orientata agli oggetti.

- -
var obj = {
-    // __proto__
-    __proto__: theProtoObj,
-    // Abbreviazione per ‘handler: handler’
-    handler,
-    // Metodi
-    toString() {
-     // Super calls
-     return "d " + super.toString();
-    },
-    // Nomi di proprietà calcolati (dinamici)
-    [ 'prop_' + (() => 42)() ]: 42
-};
- -

Nota che:

- -
var foo = {a: "alpha", 2: "two"};
-console.log(foo.a);    // alpha
-console.log(foo[2]);   // two
-//console.log(foo.2);  // Error: missing ) after argument list
-//console.log(foo[a]); // Error: a is not defined
-console.log(foo["a"]); // alpha
-console.log(foo["2"]); // two
-
- -

Letterali di RegExp

- -

Un letterale di espressione regolare (RegExp) è un modello (pattern) racchiuso tra barre. il seguente è un esempio di un letterale di una espressione regolare.

- -
var re = /ab+c/;
- -

Letterali di stringhe

- -

Un letterale di testo (stringa nel preguo del testo) è formato da zero o più caratteri racchiusi tra virgolette doppie  (") o singole (').  Una stringa deve essere delimitata da virgolette dello stesso tipo; cioè o entrambe singole o entrambe doppie. I seguenti sono esempi di leterali di testo:

- -
"foo"
-'bar'
-"1234"
-"una linea \n altra linea"
-"prima dell'una"
-
- -

È possibile chiamare qualsiasi metodo dell'oggetto String su una stringa —JavaScript converte automaticamente la stringa in un oggetto temporaneo di tipo String, chiama il metodo, poi elimina l'oggetto temporaneo. È anche possibile usare la proprietà String.length con una stringa letterale:

- -
console.log("John's cat".length)
-// Stamperà il numero di simboli nel testo inclusi gli spazi.
-// In questo caso 10.
-
- -

In ES2015 sono disponibili i letterali modello. I letterali modello sono racchiusi tra accenti gravi (` `)  (accento grave) anziché apici doppi o singoli. Le stringhe modello fornisco dello "zucchero sintattico" per la costruzione delle stringhe. È simile all'interpolazione delle stringhe di Perl, Python e altri. Opzionalmente, un'etichetta può essere aggiunta per permettere la personalizzazione nella costruzione della stringa, evitare gli attacchi per injection o costruire strutture dati di livello più alto dal contenuto di una stringa.

- -
// Creazione di un letterale string di base
-`In JavaScript '\n' is a line-feed.`
-
-// Stringa multilinea
-`In JavaScript this is
- not legal.`
-
-// Interpolazione di stringhe
-var name = "Bob", time = "today";
-`Hello ${name}, how are you ${time}?`
-
-// La costruzione di un prefisso di richiesta HTTP è usata per interpretare le sostituzioni e le costruzioni
-POST`http://foo.org/bar?a=${a}&b=${b}
-     Content-Type: application/json
-     X-Credentials: ${credentials}
-     { "foo": ${foo},
-       "bar": ${bar}}`(myOnReadyStateChangeHandler);
- -

Si dovrebbero usare i letterali stringa a meno che non ci sia specifico bisogno di usare un oggetto String. Si veda {{jsxref("String")}} per dettagli sull'oggetto String.

- -

Uso di caratteri speciali nelle stringhe

- -

Oltre ai caratteri ordinari si possono includere anche dei caratteri speciali nelle stringhe come mostrato nel seguente esempio.

- -
"prima linea \n seconda linea"
-
- -

La seguente tabella elenca i caratteri speciali che possono essere usati nelle stringhe JavaScript.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Table: JavaScript caratteri speciali
CarattereSignificato
\0Byte null
\bBackspace
\fForm feed
\nNew line
\rCarriage return
\tTab
\vTab verticale
\'Apostrofo o virgoletta singola
\"Virgoletta doppia
\\Il carattere backslash
\XXXIl carattere con la codifica Latin-1 specificata da fino a tre caratteri XXX tra 0 e 377. Per esempio \251 è la sequenza ottale per il simbolo di copyright.
\xXXIl carattere con la codifica Latin-1 specificata da due cifre esadecimali XX comprese tra 00 e FF. Per esempio \xA9 è la sequenza ottale per il simbolo di copyright.
\uXXXXIl carattere Unicode specificato da quattro cifre esadecimali XXXX. Per esempio \u00A9 è la sequenza Unicode per il simbolo di copyright. Vedi Unicode escape sequences.
\u{XXXXX}Escape per Unicode code point. Per esempio \u{2F804} è la stessa cosa dell'esape semplice Unicode \uD87E\uDC04.
- -

Caratteri a cui aggiungere il backslash (Escaping)

- -

Per i caratteri non elencati nella tabella un backslash (\) prefisso viene ignorato, questo uso è deprecato e devrebbe essere evitato.

- -

Le virgolette possono essere inserite in una stringa precedendole da un backslash. Questo è noto come escaping delle virgolette. Per esempio:

- -
var quote = "Lui legge \"The Cremation of Sam McGee\" by R.W. Service.";
-console.log(quote);
-
- -

Il risultato sarebbe:

- -
Lui legge "The Cremation of Sam McGee" by R.W. Service.
-
- -

Per includere un backslash in una stringa va fatto l'esape del carattere backslash. Per esempio, per assegnare il percorso c:\temp ad una stringa, usare il seguente:

- -
var home = "c:\\temp";
-
- -

Si può anche fare l'escape delle interruzioni di linea precedendole con un backslash. Sia il backslash che l'interruzione di linea saranno rimosse dal valore della stringa.

- -
var str = "questa stringa \
-è spezzata \
-attraverso multiple\
-linee."
-console.log(str);   // questa stringa è spezzata attraverso multiple linee.
-
- -

Sebbene JavaScript non abbia una sintassi tipo "heredoc", è possibile fare qualcosa di simile aggiungendo una sequenza di escape per "a capo" e facendo l'escape dell'a capo alla fine della linea:

- -
var poem =
-"Roses are red,\n\
-Violets are blue.\n\
-I'm schizophrenic,\n\
-And so am I."
-
- -

Ulteriori informazioni

- -

Questo capitolo si concentra sulla sintassi di base per i tipi e le dichiarazioni. Per imparare di più riguardo i costrutti del linguaggio JavaScript vedi anche i seguenti capitoli in questa guida:

- - - -

Nel prossimo capitolo, tratteremo i costrutti del controllo del flusso e la gestione degli errori.

- -

{{PreviousNext("Web/JavaScript/Guide/Introduction", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}

diff --git a/files/it/web/javascript/guida/index.html b/files/it/web/javascript/guida/index.html deleted file mode 100644 index ba956f21f2..0000000000 --- a/files/it/web/javascript/guida/index.html +++ /dev/null @@ -1,124 +0,0 @@ ---- -title: JavaScript Guide -slug: Web/JavaScript/Guida -tags: - - AJAX - - JavaScript - - JavaScript_Guide - - NeedsTranslation - - TopicStub -translation_of: Web/JavaScript/Guide ---- -
{{jsSidebar("JavaScript Guide")}}
- -

La Guida JavaScript mostra come utilizzare JavaScript e offre una panoramica del linguaggio. Se hai bisogno di informazioni esaustive su una sua funzione, dai un'occhiata alle reference JavaScript.

- -

Capitoli

- -

Questa guida è divisa in vari capitoli:

- - - - - - - - - -

{{Next("Web/JavaScript/Guide/Introduction")}}

diff --git a/files/it/web/javascript/guida/introduzione/index.html b/files/it/web/javascript/guida/introduzione/index.html deleted file mode 100644 index 3825ded91c..0000000000 --- a/files/it/web/javascript/guida/introduzione/index.html +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: Introduzione -slug: Web/JavaScript/Guida/Introduzione -tags: - - Guida - - JavaScript -translation_of: Web/JavaScript/Guide/Introduction ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammar_and_types")}}
- -

Questo capitolo introduce JavaScript e discute alcuni dei suoi concetti fondamentali.

- -

Che cosa dovresti già sapere

- -

Questa guida parte dal presupposto che tu abbia già queste nozioni di base:

- - - -

Dove trovare informazioni su JavaScript

- -

La documentazione JavaScript su MDN comprende:

- - - -

Se sei nuovo di JavaScript, inizia con gli articoli presenti in Capire il web e nella  Guida JavaScript. Quando avrai una chiara comprensione dei fondamentali, potrai usare il  Riferimento JavaScript per apprendere maggiori dettagli su singoli oggetti e parti del linguaggio.

- -

Che cos'è JavaScript?

- -

JavaScript è un linguaggio di scripting cross-platform e object-oriented. È un linguaggio piccolo e leggero. All interno di un ambiente ospite (ad esempio un web browser), JavaScript può essere connesso agli oggetti del suo ambiente per fornire controllo programmatico su di essi.

- -

JavaScript contiene una libreria standard di oggetti come Array, Date e Math, ed una serie di elementi base del linguaggio come operatori, strutture di controllo e dichiarazioni. La base di JavaScript può essere estesa per una varietà di scopi fornendogli oggetti aggiuntivi; ad esempio:

- - - -

JavaScript e Java

- -

JavaScript e Java sono simili per certi aspetti, ma fondamentalmente diversi per altri. Il linguaggio JavaScript assomiglia a Java ma non ha la tipizzazione statica ed il controllo forte dei tipi di Java. JavaScript segue larga parte della sintassi delle espressioni di Java, la convenzione sui nomi ed i principali costrutti di controllo di flusso, e questa è la ragione per cui è stato rinominato da LiveScript a JavaScript.
- A differenza del sistema di classi costruito dalle dichiarazione a tempo di compilazione di Java, JavaScript supporta un sistema runtime basato su un piccolo numero di tipi di dato che rappresentano valori Booleani, numerici e di tipo stringa. JavaScript dispone di un modello ad oggetti basato su prototype al posto del più comune modello ad oggetti basato su classi. Il modello prototype-based fornisce ereditarietà dinamica; che significa che ciò che viene ereditato può variare per singoli oggetti. JavaScript inoltre supporta funzioni senza speciali requisiti dichiarativi. Le funzioni possono essere proprietà di oggetti, eseguite come metodi debolmente tipizzati.

- -

JavaScript è un linguaggio con un formalismo molto libero se confrontato a Java. Non è necessario dichiarare tutte le variabili, classi e metodi. Non ci si deve preoccupare se i metodi sono public, privare e protected, e non è necessario implementare interfacce. Variabili, parametri e valori di ritorno delle funzioni non sono tipizzati in modo esplicito.

- -

Java è un linguaggio di programmazione basato su classi progettato per essere veloce e con un controllo dei tipi rigoroso. Con controllo dei tipi rigoroso si intende per esempio, che non è possibile forzare un intero Java in un riferimento ad oggetto o accedere alla memoria privata corrompendo i bytecodes Java. Il modello basato sulle classi di Java significa che i programmi sono composti esclusivamente da classi con i propri metodi. L'ereditarietà delle classi di Java e la tipizzazione forte di solito richiedono gerarchie di oggetti strettamente definite. Questi requisiti rendono la programmazione di Java più complessa rispetto alla programmazione di JavaScript.

- -

D'altra parte, JavaScript si ispira ad una linea di linguaggi più piccoli, tipizzati dinamicamente come HyperTalk e dBASE. Questi linguaggi di scripting offrono strumenti di programmazione ad un pubblico più vasto grazie alla loro sintassi più facile, alle funzionalità specializzate predefinite nel linguaggio, ed ai minimi requisiti per la creazione di oggetti.

- - - - - - - - - - - - - - - - - - - - - - - -
JavaScript confrontato con Java
JavaScriptJava
-

Orientato ad oggetti. Non c'è distinzione tra tipi di oggetti. Ereditarietà con il meccanismo dei prototype e le proprietà ed i metodi possono essere aggiunti ad ogni oggetto dinamicamente.

-
-

Basato su classi. Gli oggetti vengono distinti in classi ed istanze con tutta l'ereditarietà costruita con lagerarchia delle classi. Classi ed istanze non possono avere proprietà o metodi aggiunti dinamicamente.

-
Le variabili ed i tipi non sono dichiarati (tipizzazione dinamica).Le variabili ed i tipi di dato devono essere dichiarati (tipizzazione statica).
Non si può scrivere automaticamente suk disco fisso.Si può scrivere automaticamente su disco fisso.
- -

Per maggiori informazioni sulle differenze tra JavaScript e Java, vedi il capitolo Dettagli sul modello ad oggetti.

- -

JavaScript e le specifiche ECMAScript

- -

JavaScript è standardizzato da Ecma International — l'associazione Europea per la standardizzazione dei sisteni di comunicazione ed informazione (ECMA è l'acronimo di European Computer Manufacturers Association) per distribuire linguaggio di programmazione standardizzato ed internazionale basato su JavaScript. Questa versione standardizzata di JavaScript, chiamata ECMAScript, si comporta alla stesso modo in tutte le applicazioni che supportano lo standard. Le aziende possono usare il linguaggo standard aperto per svilupare le proprie implementazioni di JavaScript. Lo standard ECMAScript è documentato nelle specifiche ECMA-262. Consulta Novità in JavaScript per conoscere di più sulle differenti versioni di JavaScript e delle edizioni delle specifiche ECMAScript.

- -

Lo standard ECMA-262 è anche approvato da ISO (International Organization for Standardization) come ISO-16262. Si possono trovare le specifiche nel sito Ecma internazionale. Le specifiche ECMAScript non descrivono il Document Object Model (DOM), che viene standardizzato dal World Wide Web Consortium (W3C). Il DOM definisce il modo in cui gli oggetti di un documento HTML vengono esposti al tuo script. Per farti un'idea migliore sulle differenti tecnologie che si usano quando si programma con JavaScript, consulta l'articolo Panoramicha delle tecnologie JavaScript.

- -

Documentazione JavaScript a confronto con le specifiche ECMAScript

- -

Le specifiche ECMAScript sono una serie di requisiti per implementare ECMAScript; sono utili per chi desidera implementare funzionalità compatibili con lo standard del linguaggio nella propria implementazione di ECMAScript (come SpiderMonkey in Firefox, o v8 in Chrome).

- -

La documentazione ECMAScript non è indirizzata ad aiutare i programmatori di script; usa la documentazione di JavaScript per informazioni su come scrivere script.

- -

Le specifiche ECMAScript usano terminologie e sintassi che possono risultare non  familiari ai programmatori JavaScript Sebbene la descrizione del linguaggio possa essere diversa in ECMAScript, il linguaggio in se rimane lo stesso. JavaScript supporta tutte le funzionalità descritte nelle specifiche ECMAScript.

- -

La documentazione JavaScript descrive aspetti del linguaggio che sono appropriati per il programmatore JavaScript.

- -

Iniziare con JavaScript

- -

Iniziare con JavaScript è facile: la sola cosa che serve è un Web browser moderno. Questa guida include alcune funzionalità di JavaScript che sono attualmente disponibili solo nell'ultima versione di Firefox, per questo raccomandiamo di usare la versione più recente di Firefox.

- -

In Firefox sono presenti due strumenti che sono utili per sperimentare con JavaScript: la Console Web ed il Blocco per gli appunti.

- -

La Console Web

- -

La Console Web espone informazioni sulla pagina Web attualmente caricata, ed include una command line che si può usare per eseguire espressioni nella pagina corrente.

- -

Per aprire la Console Web (Ctrl+Shift+K), scegli "Console web" dal menu "Sviluppo web", che si trova nel menu "Strumenti" di Firefox. Essa appare sotto la finestra del browser. Alla fine della console è presente la linea di comando che si può usare per inserire comandi JavaScript ed il risultato compare nel pannello soprastante:

- -

- -

Blocco per gli appunti

- -

La Console Web è magnifica per eseguire singole linee di JavaScript, ma sebbene si possano eseguire linee multiple, non è molto comoda per questo e non è possibile salvare i propri esempi di codice con la Console Web. Quindi per esempi più complessi di codice il Blocco per gli appunti è uno strumento migliore.

- -

Per aprire il Blocco per gli appunti (Shift+F4), scegli "Blocco per gli appunti" dal menu "Sviluppo web", che si trova nel menu "Strumenti" di Firefox. Si apre in una finestra separata ed un editor che puoi usare per scrivere ed eseguire JavaScript nel browser. Si possono anche salvare scripts nel disco e caricare scripts salvati.

- -

- -

Hello world

- -

Per iniziare a scrivere programmi JavaScript, apri il Blocco per gli appunti e scrivi il tuo primo codice "Hello world" JavaScript:

- -
function greetMe(yourName) {
-  alert("Hello " + yourName);
-}
-
-greetMe("World");
-
- -

Seleziona il codice nel blocco e premi Ctrl+R per vedere il risultato nel browser!

- -

Nelle prossime pagine, questa guida ti itrodurra alla sintassi di JavaScript ed alle caratteristiche del linguaggio, in questo modo sarai in grado di scrivere applicazioni più complesse.

- -

{{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammar_and_types")}}

diff --git a/files/it/web/javascript/guida/iteratori_e_generatori/index.html b/files/it/web/javascript/guida/iteratori_e_generatori/index.html deleted file mode 100644 index 49b220cdd1..0000000000 --- a/files/it/web/javascript/guida/iteratori_e_generatori/index.html +++ /dev/null @@ -1,162 +0,0 @@ ---- -title: Iteratori e generatori -slug: Web/JavaScript/Guida/Iteratori_e_generatori -translation_of: Web/JavaScript/Guide/Iterators_and_Generators ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Meta_programming")}}
- -

Processare ognuno degli elementi in una collezione è un'operazione molto comune. JavaScript fornisce tutta una serie di costrutti per iterare una collezione di elementi, dai semplici cicli {{jsxref("Statements/for","for")}} a {{jsxref("Global_Objects/Array/map","map()")}} e {{jsxref("Global_Objects/Array/filter","filter()")}}. Iterators e Generators portano il concetto di iterazione direttamente al cuore del linguaggio e forniscono un meccanismo per personalizzare i cicli {{jsxref("Statements/for...of","for...of")}}.

- -

Per maggiori dettagli, vedi anche:

- - - -

Iterators

- -

Un oggetto è un iterator quando sa come accedere agli elementi di una collezione uno per volta, conservando l'informazione sulla sua posizione corrente nella sequenza. In Javascript un iterator è un oggetto che implementa il metodo next() , il quale ritorna l'elemento successivo della sequenza. Questo metodo ritorna un oggetto con due proprietà: done evalue.

- -

Una volta che è stato creato, un iterator può essere utlizzato esplicitamente chiamando più volte il metodo next().

- -
function makeIterator(array) {
-    var nextIndex = 0;
-
-    return {
-       next: function() {
-           return nextIndex < array.length ?
-               {value: array[nextIndex++], done: false} :
-               {done: true};
-       }
-    };
-}
- -

Una volta che un iterator è stato inizializzato, il metodonext() può essere chiamato per accedere a coppie chiave-valore dall'oggetto ritornato:

- -
var it = makeIterator(['yo', 'ya']);
-console.log(it.next().value); // 'yo'
-console.log(it.next().value); // 'ya'
-console.log(it.next().done);  // true
- -

Generators

- -

Nonostante implementare un iterator possa essere utile, richiede una considerevole attenzione nella programmazione a causa del bisogno esplicito di mantenere lo stato interno dell'iteratore. I {{jsxref("Global_Objects/Generator","Generators","","true")}} forniscono una potente alternativa: ti permettono di definire un algoritmo iterativo scrivendo una singola funzione in grado di mantenere il proprio stato.

- -

Una GeneratorFunction è uno speciale tipo di funzione che opera come una "fabbrica" di iterators. Quando viene eseguita ritorna un nuovo oggetto Generator. Una funzione diventa una GeneratorFunction se usa la sintassi {{jsxref("Statements/function*","function*")}}.

- -
function* idMaker() {
-  var index = 0;
-  while(true)
-    yield index++;
-}
-
-var gen = idMaker();
-
-console.log(gen.next().value); // 0
-console.log(gen.next().value); // 1
-console.log(gen.next().value); // 2
-// ...
- -

Iterables

- -

Un oggetto è un iterable se definisce un comportamento di iterazione, come per esempio quali valori sono considerati in un costrutto {{jsxref("Statements/for...of", "for...of")}}. Alcuni tipi built-in di Javascript (come {{jsxref("Array")}} o {{jsxref("Map")}}) hanno un comportamento predefinito, mentre altri tipi (come {{jsxref("Object")}}) non ce l'hanno.

- -

Affinché un oggetto possa essere considerato un iterable deve implementare il metodo @@iterator, cioè l'oggetto (o uno degli oggetti che lo precedono nella catena dei prototipi) deve avere una proprietà con una chiave {{jsxref("Symbol.iterator")}}.

- -

Iterables definiti dall'utente

- -

Possiamo creare i nostri iterables in questo modo:

- -
var myIterable = {};
-myIterable[Symbol.iterator] = function* () {
-    yield 1;
-    yield 2;
-    yield 3;
-};
-
-for (let value of myIterable) {
-    console.log(value);
-}
-// 1
-// 2
-// 3
-
-or
-
-[...myIterable]; // [1, 2, 3]
-
- -

Iterables Built-in

- -

{{jsxref("String")}}, {{jsxref("Array")}}, {{jsxref("TypedArray")}}, {{jsxref("Map")}} e {{jsxref("Set")}} sono tutti iterables built-in nel linguaggio, perché i loro oggetti prototipi hanno tutti un metodo {{jsxref("Symbol.iterator")}}.

- -

Sintassi che si aspettano degli iterables

- -

Alcuni costrutti ed espressioni si aspettano degli iterables, per esempio il ciclo {{jsxref("Statements/for...of","for-of")}}, la {{jsxref("Operators/Spread_operator","sintassi spread","","true")}}, {{jsxref("Operators/yield*","yield*")}}, e l'{{jsxref("Operators/Destructuring_assignment","assegnamento di destrutturazione","","true")}}.

- -
for (let value of ['a', 'b', 'c']) {
-    console.log(value);
-}
-// "a"
-// "b"
-// "c"
-
-[...'abc']; // ["a", "b", "c"]
-
-function* gen() {
-  yield* ['a', 'b', 'c'];
-}
-
-gen().next(); // { value: "a", done: false }
-
-[a, b, c] = new Set(['a', 'b', 'c']);
-a; // "a"
-
-
- -

Generators avanzati

- -

I generators calcolano i loro valori solo quando vengono effettivamente richiesti, il che gli permette di rappresentare sequenze che sono troppo onerose da calcolare, o perfino sequenze infinite, come nella funzione idMaker().

- -

Il metodo {{jsxref("Global_Objects/Generator/next","next()")}} accetta anche un valore che può essere utilizzato per modificare lo stato interno di un generatore. Un valore passato a next() sarà trattato come il risultato dell'ultima espressione yield che ha messo in pausa il generator.

- -

Ecco un generator che produce una sequenza di numeri di Fibonacci. In questo generator il metodonext(x) può essere utilizzato per reinizializzare la sequenza:

- -
function* fibonacci() {
-  var fn1 = 0;
-  var fn2 = 1;
-  while (true) {
-    var current = fn1;
-    fn1 = fn2;
-    fn2 = current + fn1;
-    var reset = yield current;
-    if (reset) {
-        fn1 = 0;
-        fn2 = 1;
-    }
-  }
-}
-
-var sequence = fibonacci();
-console.log(sequence.next().value);     // 0
-console.log(sequence.next().value);     // 1
-console.log(sequence.next().value);     // 1
-console.log(sequence.next().value);     // 2
-console.log(sequence.next().value);     // 3
-console.log(sequence.next().value);     // 5
-console.log(sequence.next().value);     // 8
-console.log(sequence.next(true).value); // 0
-console.log(sequence.next().value);     // 1
-console.log(sequence.next().value);     // 1
-console.log(sequence.next().value);     // 2
- -

Puoi forzare un generator a lanciare una eccezione chiamando il suo metodo {{jsxref("Global_Objects/Generator/throw","throw()")}} e passandogli il valore che dovrebbe lanciare. Questa eccezione sarà lanciata dal corrente context sospeso del generator, come se lo yield che è attualmente sospeso fosse invece una dichiarazione throw value.

- -

Se non si incontra uno yield durante la risoluzione della eccezione lanciata, allora l'eccezione si propagherà fino alla chiamata athrow(), e in tutte le successive chiamate a next() la proprietà done saràtrue.

- -

I generators hanno un metodo {{jsxref("Global_Objects/Generator/return","return(value)")}} che ritorna un valore e termina il generator stesso.

- -

{{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Meta_programming")}}

diff --git a/files/it/web/javascript/guida/loops_and_iteration/index.html b/files/it/web/javascript/guida/loops_and_iteration/index.html deleted file mode 100644 index c677151181..0000000000 --- a/files/it/web/javascript/guida/loops_and_iteration/index.html +++ /dev/null @@ -1,340 +0,0 @@ ---- -title: Cicli e iterazioni -slug: Web/JavaScript/Guida/Loops_and_iteration -tags: - - Guide - - JavaScript - - Loop - - Sintassi -translation_of: Web/JavaScript/Guide/Loops_and_iteration ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}
- -

I cicli offrono un modo semplice e rapido per fare cose ripetutamente. Questo capitolo della guida al JavaScript introduce i diversi metodi di iterazione disponibili in JavaScript.

- -

Si può pensare al loop come ad una versione computerizzata di un gioco dove si dice a qualcuno di andare X passi in una direzione e Y passi in un'atra; per esempio "vai 5 passi a est" può essere espresso in questo modo con un loop:

- -
var passi;
-for (passi = 0; passi < 5; passi++) {
-  // Viene eseguito 5 volte, con un valore di passi che va da 0 a 4.
-  console.log('Fai un passo verso est');
-}
-
- -

Ci sono differenti tipi di ciclo, ma sono essenzialmente tutti la stessa cosa: ripetono un'azione o un insieme di azioni un certo numero di volte (è possibile che questo numero sia anche 0).

- -

I diversi meccanismi di ciclo offrono differenti modi di determinare l'inizio e la fine del ciclo. Ci sono casi che si prestano più ad un tipo di ciclo rispetto ad altri.

- -

Le istruzioni per i loop foriti in JavaScript sono:

- - - -

Istruzione for

- -

Il {{jsxref("statements/for","ciclo for")}} continua finché la condizione valutata non è falsa. Il fir loop JavaScript è simile a quello del Java e de C. L'istruzione for è definita come segue:

- -
for ([espressioneIniziale]; [condizione]; [incremento])
-  istruzione
-
- -

Quando viene eseguito un ciclo for, questo è ciò che accade:

- -
    -
  1. espressioneIniziale, se esiste, viene eseguita. L'espressione di solito inizializza uno o più indici, ma la sintassi permette di scrivere espressioni con diversi gradi di compessità. Questa espressione può anche dichiarare delle variabili.
  2. -
  3. La condizione viene verificata. Se il suo valore è true, l'espressione istruzione viene eseguita. Se invece condizione è false, il ciclo finisce. Se condizione è omessa, l'espressione si assume sia true.
  4. -
  5. istruzione viene esguita. Per eseguire diverse istruzioni, è necessario usare il blocco ({ ... }) per raggrupparle.
  6. -
  7. Viene incrementata la l'espressione incremento, se esiste, eseguita, e il ciclo for va al passo successivo.
  8. -
- -

Esempio

- -

Il seguente esempio contiene un ciclo for che conta il numero di opzioni selezionate in una lista a scorrimento (a {{HTMLElement("select")}} che permette selezioni multiple). L'istruzione for dichiara una variabile i e la inizializza a zero. Controlla che i sia minore del numero di opzioni dell'elemento <select> , esegue l'istruzione if e incrementa i di uno alla fine di ogni ciclo.

- -
<form name="selectForm">
-  <p>
-    <label for="musicTypes">Choose some music types, then click the button below:</label>
-    <select id="musicTypes" name="musicTypes" multiple="multiple">
-      <option selected="selected">R&B</option>
-      <option>Jazz</option>
-      <option>Blues</option>
-      <option>New Age</option>
-      <option>Classical</option>
-      <option>Opera</option>
-    </select>
-  </p>
-  <p><input id="btn" type="button" value="Quanti sono selezionati?" /></p>
-</form>
-
-<script>
-function howMany(selectObject) {
-  var numberSelected = 0;
-  for (var i = 0; i < selectObject.options.length; i++) {
-    if (selectObject.options[i].selected) {
-      numberSelected++;
-    }
-  }
-  return numberSelected;
-}
-
-var btn = document.getElementById("btn");
-btn.addEventListener("click", function(){
-  alert('Number of options selected: ' + howMany(document.selectForm.musicTypes))
-});
-</script>
-
-
- -

Istruzione do...while

- -

Il ciclo {{jsxref("statements/do...while", "do...while")}} si ripete finché la condizione non è falsa. Il do...while è viene definito come segue:

- -
do
-  istruzione
-while (condizione);
-
- -

l'istruzione viene eseguita una volta prima che la condizione venga controllata. Per eseguire più istruzioni, è necessario usare il blocco ({ ... }) . Se la condizione è vera l'istruzione viene eseguita nuovamente. Alla fine di ogni esecuzione di istruzione, condizione viene controllata. Quando condizione è falsa l'esecuzione del ciclo do..while termina.

- -

Esempio

- -

Nel seguente esempio il ciclo do..while itera almeno una volta e continua finché il valore di i è minore di 5.

- -
var i = 0;
-do {
-  i += 1;
-  console.log(i);
-} while (i < 5);
- -

Istruzione while

- -

Il ciclo {{jsxref("statements/while","while")}} esegue un'istruzione fino a quando una condizione è true. Ecco un esempio si un ciclo while:

- -
while (condizione)
-  istruzione   //...statement
-
- -

Se condizione diventa false, istruzione non viene eseguita a si passa ad eseguire i comandi successivi.

- -

Durante il ciclo condizione viene testata prima di eseguire istruzione. Se condizione è true, istruzione viene esguita e condizione viene verificata nuovamente. Se condizione è false il ciclo di ferma e viene eseguito il codice successivo al ciclo while.

- -

Per eseguire istruzioni multiple, è necessario usare il blocco ({ ... }) così da raggruppare le istruzioni.

- -

Esempio 1

- -

Il seguente esempio di ciclo while si ripete fino a quando n è minore di tre:

- -
var n = 0;
-var x = 0;
-while (n < 3) {
-  n++;
-  x += n;
-}
-
- -

Ad ogni iterazione, il ciclo incrementa n e aggiunge quel valore a x. Pertanto,x e n assumono i seguenti valori:

- - - -

Dopo aver completato il terzo passaggio, la condizione n < 3 non è più vera, quindi il ciclo termina.

- -

Esempio 2

- -

Evita loop infiniti. Assicurati che la condizione in un loop alla fine diventi falsa; altrimenti, il ciclo non terminerà mai. Le istruzioni nel seguente ciclo while vengono eseguite per sempre perché la condizione non diventa mai falsa:

- -
-
//I loop infiniti non vanno affatto bene
-while (true) {
-  console.log("Buongiorno, Mondo");
-}
-
- -

Istruzione "etichettata"

- -

Un {{jsxref("statements/label","label")}} fornisce un'istruzione con un identificatore che ti consente di fare riferimento ad esso altrove nel tuo programma. Ad esempio, è possibile utilizzare un'etichetta per identificare un ciclo e quindi utilizzare le istruzioni breakcontinue per indicare se un programma deve interrompere il loop o continuare la sua esecuzione.

- -

La sintassi dell'istruzione etichettata è simile alla seguente:

- -
label :
-   istruzione // statement
-
- -

Il valore dell'etichetta label può essere qualsiasi identificatore JavaScript che non sia una parola riservata. L'affermazione che ti identifichi con un'etichetta statement può essere una qualsiasi affermazione.

- -

Esempio

- -

In questo esempio, la label markLoop identifica un ciclo while.

- -
markLoop:
-while (theMark == true) {
-   doSomething();
-}
- -

Istruzione break

- -

Utilizzare l'istruzione {{jsxref("statements/break","break")}} per terminare un ciclo, uno switch o in congiunzione con un'istruzione etichettata.

- - - -

La sintassi dell'istruzione break è simile a questa:

- -
break [label];
-
- -

La prima forma della sintassi termina il ciclo switch di chiusura più interno; la seconda forma della sintassi termina l'istruzione dell'etichettata specificata.

- -

Esempio 1

- -

L'esempio seguente esegue iterazioni attraverso gli elementi di un array (una matrice) fino a quando non trova l'indice di un elemento il cui valore è theValue:

- -
for (var i = 0; i < a.length; i++) {
-  if (a[i] == theValue) {
-    break;
-  }
-}
- -

Esempio 2: Breaking to a label - Interruzione su un'etichetta

- -
var x = 0;
-var z = 0;
-labelCancelLoops: while (true) {
-  console.log("Outer loops: " + x);
-  x += 1;
-  z = 1;
-  while (true) {
-    console.log("Inner loops: " + z);
-    z += 1;
-    if (z === 10 && x === 10) {
-      break labelCancelLoops;
-    } else if (z === 10) {
-      break;
-    }
-  }
-}
- -

Istruzione continue

- -

The {{jsxref("statements/continue","continue")}} statement can be used to restart a while, do-while, for, or label statement.

- - - -

La sintassi dell'istruzione continue ha il seguente aspetto:

- -
continue [label];
-
- -

Esempio 1

- -

L'esempio seguente mostra un ciclo while con un'istruzione continue che viene eseguita quando il valore di i è tre. Quindi, n assume i valori uno, tre, sette e dodici.

- -
var i = 0;
-var n = 0;
-while (i < 5) {
-  i++;
-  if (i == 3) {
-    continue;
-  }
-  n += i;
-}
- -

Esempio 2

- -

Una dichiarazione etichettata checkiandj contiene una dichiarazione etichettata checkj. Se si incontra continue il programma termina l'iterazione corrente di checkj e inizia la successiva iterazione. Ogni volta che si incontra continue, checkj viene reiterato finché la condizione non restituisce false. Quando viene restituito false, il resto dell'istruzione checkiandj è completato e checkiandj reiterate fino a quando la condizione non restituisce false. Quando viene restituito false, il programma continua con la seguente istruzione checkiandj.

- -

Se continue ha un'etichetta di checkiandj, il programma continuerà nella parte superiore del checkiandj istruzione.

- -
var i = 0;
-var j = 10;
-checkiandj:
-  while (i < 4) {
-    console.log(i);
-    i += 1;
-    checkj:
-      while (j > 4) {
-        console.log(j);
-        j -= 1;
-        if ((j % 2) == 0) {
-          continue checkj;
-        }
-        console.log(j + ' is odd.');
-      }
-      console.log('i = ' + i);
-      console.log('j = ' + j);
-}
- -

Istruzione for...in

- -

L'istruzione {{jsxref("statements/for...in","for...in")}} itera una variabile specificata su tutte le proprietà enumerabili di un oggetto. Per ogni proprietà distinta, JavaScript esegue le istruzioni specificate. L'istruzione for...in ha il seguente aspetto:

- -
for (variabile in oggetto) {
-  istruzione
-}
-// for (variable in object) {
-//  statements
-// }
-
- -

Esempio

- -

La seguente funzione prende come argomento un oggetto e il nome dell'oggetto. Quindi itera su tutte le proprietà dell'oggetto e restituisce una stringa che elenca i nomi delle proprietà e i loro valori.

- -
function dump_props(obj, obj_name) {
-  var result = "";
-  for (var i in obj) {
-    result += obj_name + "." + i + " = " + obj[i] + "<br>";
-  }
-  result += "<hr>";
-  return result;
-}
-
- -

Per un oggetto car con proprietà make e model, result sarebbe:

- -
car.make = Ford
-car.model = Mustang
-
- -

Arrays / Matrici

- -

Anche se può essere allettante usarla come un modo per iterare sugli elementi {{jsxref("Array")}} , l'istruzione the for...in restituirà il nome delle proprietà definite dall'utente oltre agli indici numerici. Quindi è meglio usare un ciclo tradizionale {{jsxref("statements/for","for")}} con un indice numerico quando si itera su array, perché l'istruzione for...in itera sulle proprietà definite dall'utente oltre agli elementi dell'array, se si modifica l'oggetto Array, (come ad esempio l'aggiunta di proprietà o metodi personalizzati).

- -

Istruzione for...of

- -

L'istruzione {{jsxref("statements/for...of","for...of")}} crea un ciclo che itera su oggetti iterabili (inclusi oggetti di tipo {{jsxref("Array")}}, {{jsxref("Map")}}, {{jsxref("Set")}}, {{jsxref("functions/arguments","arguments")}} e così via), richiamando un aggancio di iterazione personalizzato con istruzioni da eseguire per il valore di ogni proprietà distinta.

- -
for (variabile di oggetto) {
-  istruzione
-}
- -

Il seguente esempio mostra la differenza tra un ciclo for...of e un {{jsxref("statements/for...in","for...in")}} ciclo continuo. Mentre for...in itera sopra i nomi delle proprietà, for...of itera sui valori delle proprietà:

- -
let arr = [3, 5, 7];
-arr.foo = "hello";
-
-for (let i in arr) {
-   console.log(i); // logs "0", "1", "2", "foo"
-}
-
-for (let i of arr) {
-   console.log(i); // logs "3", "5", "7"
-}
- -

{{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}

diff --git a/files/it/web/javascript/guide/control_flow_and_error_handling/index.html b/files/it/web/javascript/guide/control_flow_and_error_handling/index.html new file mode 100644 index 0000000000..76e72f5cba --- /dev/null +++ b/files/it/web/javascript/guide/control_flow_and_error_handling/index.html @@ -0,0 +1,461 @@ +--- +title: Controllo del flusso di esecuzione e gestione degli errori +slug: Web/JavaScript/Guida/Controllo_del_flusso_e_gestione_degli_errori +tags: + - Controllo di flusso + - Guide + - JavaScript + - Principianti + - 'l10n:priority' +translation_of: Web/JavaScript/Guide/Control_flow_and_error_handling +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Grammar_and_types", "Web/JavaScript/Guide/Loops_and_iteration")}}
+ +

JavaScript prevede un insieme di istruzioni compatto, specifico per il controllo del flusso di esecuzione, che si può utilizzare per aggiungere un'elevata interattività alle proprie applicazioni. Questo capitolo fornisce una panoramica su queste istruzioni.

+ +

Il JavaScript reference contiene dettagli esaustivi sulle istruzioni di questo capitolo. Il carattere punto e virgola (;) è usato per separare le varie istruzioni del codice JavaScript.

+ +

Ogni espressione JavaScript è a sua volta un'istruzione. Si veda a riguardo Espressioni ed operatori per una completa descrizione delle espressioni.

+ +

Costrutto di blocco

+ +

Un costrutto fondamentale è il blocco, usato per raggruppare insieme più istruzioni, delimitato da un paio di parentesi graffe ({}):

+ +
{
+  istruzione_1;
+  istruzione_2;
+  .
+  .
+  .
+  istruzione_n;
+}
+
+ +

Esempi

+ +

Il blocco è comunemente usato assieme alle istruzioni per il controllo del flusso (e.g. if, for, while).

+ +
while (x < 10) {
+  x++;
+}
+
+ +

Qui, { x++; } rappresenta un blocco.

+ +

Importante: JavaScript prima di ECMAScript2015 non aveva la visibilità di blocco. Le variabili definite nel blocco hanno una visibilità a livello di funzione o di script in cui sono contenute e l'effetto di assegnare loro un valore persiste oltre il blocco stesso. Cioè il blocco non definisce un campo di visibilità. I blocchi "Indipendenti" ("Standalone" blocks) in JavaScript possono dare un risultato differente da quello che avrebbero prodotto in C o in Java. Per esempio:

+ +
var x = 1;
+{
+  var x = 2;
+}
+console.log(x); // produce 2
+
+ +

Risulta 2 perché l'istruzione di definizione var x dentro il blocco ha lo stesso campo di visibilità dell'istruzione var x al di fuori del blocco. Mentre in C o Java, il codice equivalente avrebbe prodotto 1.

+ +

A partire da ECMAScript2015, la dichiarazione di variabile con l'istruzione let ha visibilità di blocco. Si veda il riferimento a {{jsxref("Statements/let", "let")}} per ulteriori informazioni.

+ +

Costrutti Condizionali

+ +

Un costrutto condizionale è un insieme di istruzioni che vengono eseguite se una specifica condizione risulta vera. JavaScript prevede due costrutti condizionali: if...else e switch.

+ +

Costrutto if...else

+ +

Si usa il costrutto if per eseguire un blocco di istruzioni se una condizione logica è vera. Si usa la clausola opzionale else per eseguire istruzioni nel caso in cui la stessa condizione sia falsa. Un costrutto if...else si presenta come qui sotto:

+ +
if (condizione) {
+  istruzioni_se_vera_la_condizione;
+} else {// opzionale
+  istruzioni_se_falsa_la_condizione;
+}
+ +

Qui la condizione è qualsiasi espressione che sia valutabile come vera oppure falsa (true o false). Si veda il riferimento a Boolean per una spiegazione su cosa possa essere valutabile come true o false. Se la condizione viene valutata true, istruzioni_se_vera_la_condzione verrà eseguito, altrimenti verrà eseguito istruzioni_se_falsa_la_condzione. istruzioni_se_vera_la_condzione e istruzioni_se_falsa_la_condzione possono essere qualsiasi istruzione, incluso un altro if.

+ +

Si possono pure combinare le istruizioni else if per testare molteplici condizioni in sequenza, come il seguente codice dimostra:

+ +
if (condizione_1) {
+  istruzione_1;
+} else if (condizione_2) {
+  istruzione_2;
+} else if (condizione_n) {
+  istruzione_n;
+} else {
+  ultima_istruzione;
+}
+
+ +

Nel caso di condizioni plurime solo la prima che sia valutata come vera sarà eseguita. Per eseguire più istruzioni si devono raggruppare in un blocco ({ ... }) . In generale è buona pratica usare un blocco specialmente se si usano if annidati:

+ +
if (condizione) {
+  istruzione_1_eseguita_se_vera_la_condizione;
+  istruzione_2_eseguita_se_vera_la_condizione;
+  ...
+} else {
+  istruzione_3_eseguita_se_falsa_la_condizione;
+  istruzione_4_eseguita_se_falsa_la_condizione;
+  ...
+}
+
+ +
Non è consigliabile usare la semplice assegnazione in una espressione condizionale, perché l'assegnamento potrebbe essere confuso con il segno di uguaglianza quando si dia un'occhiata rapida al codice. Ad esempio, non si usi il seguente codice:
+ +
+ +
if (x = y) {// questa è una assegnazione
+  /* istruzioni qui */
+}
+ +

Se si deve proprio usare un assegnamento in una espressione condizionale è pratica comune aggiungere un paio di parentesi tonde attorno all'assegnamento. Per esempio:

+ +
if ((x = y)) {
+  /* istruzioni qui */
+}
+
+ +

Valori valutabili a false

+ +

I seguenti valori si valutano a false (sono anche detti {{Glossary("Falsy")}} value):

+ + + +

Tutti gli altri valori, inclusi gli oggetti, saranno valutati a true in una istruzione condizionale.

+ +

Non si confonda il valori primitivi booleani true e false con i valori true e false dell'oggetto {{jsxref("Boolean")}}. Ad esempio:

+ +
var b = new Boolean(false);
+
+if (b) // questa condizione è valutata a true
+       // perché 'b' in questo caso è un oggetto
+       // e si sa che tutti gli oggetti sono valutati a true
+
+if (b == true) // mentre questa a false,
+               // perché si va a prelevare il contenuto dell'oggetto 'b' che è false
+
+ +

Esempi

+ +

Nell'esempio a seguire la funzione controllaDati ritorna true se il numero di caratteri contenuti nella proprietà value dell'oggetto Text (treCaratteri) è tre, altrimenti mostra un popup di alert e, infine, ritorna il valore false.

+ +
function controllaDati() {
+  if (document.form1.treCaratteri.value.length == 3) {
+    return true;
+  } else {
+    alert("Immetti esattemente tre caratteri. " +
+    document.form1.treCaratteri.value + " non è valido.");
+    return false;
+  }
+}
+
+ +

Costrutto switch

+ +

Un costrutto switch permette ad un programma di valutare un'espressione e tentare di trovare la corrispondenza esatta tra il valore risultante dalla valutazione dell'espressione e l'etichetta specificata nella clausola case. Se si incontra una corrisopondenza il programma eseguirà le istruzioni associate. Un costrutto switch si presenta  come nell'esempio qui sotto riportato:

+ +
switch (espressione) {
+  case etichetta_1:
+    istruzione_1
+    [break;]// opzionale
+  case etichetta_2:
+    istruzione_2
+    [break;]
+    ...
+  default:
+    istruzioni_di_default
+    [break;]
+}
+
+ +

Il programma cerca la prima corrispondenza tra il valore ottentuto della valutazione dell'espressione e l'etichetta nella clausola case, poi trasferisce il controllo al corpo della medesima clausola eseguendo le istruzioni relative. Se non è stata trovata alcuna corrispondeza il programma va alla clausola opzionale default e, se la trova, esegue le istruizioni ad essa relative. Se non è stata data alcuna clausola default il programma continuerà con l'istruzione successiva al blocco switch. La clausola default è l'ultima che appare nel blocco switch, ma questa è una convenzione non la regola.

+ +

Il break opzionale, associato con ogni clausola case, assicura che il programma esca dal blocco switch una volta eseguite le istruzioni associate alla clausola e continui la sua esecuzione all'istruzione che segue il costrutto switch. Se il break è omesso il programma continua la sua esecuzione all'istruzione successiva nello stesso costrutto switch, ciò significa che eseguirà le istruzioni associate alla clausola case/default (se ci sono) successiva a quella appena terminata.

+ +

Esempi

+ +

Nel seguente esempio, se la variabile tipidifrutto contiene "Banane", il programma cercherà la corrispondente clausola case "Banane" ed eseguirà le istruzioni associate. Quando incontra il break, il porgramma esce dallo switch ed esegue l'istruzione successiva al blocco di switch. Se, invece, il break fosse stato omesso le istuzioni collegate con la clausola case "Ciliege" sarebbero state eseguite.

+ +
switch (tipidifrutta) {
+  case "Arance":
+    console.log("Le Arance sono a €0.59 il chilo.");
+    break;
+  case "Mele":
+    console.log("Le mele sono a €0.32 il chilo.");
+    break;
+  case "Banane":
+    console.log("Le Banane sono €0.48 il chilo.");
+    break;
+  case "Ciliege":
+    console.log("Le ciliege sono s €3.00 il chilo.");
+    break;
+  case "Mango":
+    console.log("Il Mango è è €0.56 il chilo.");
+    break;
+  case "Papaia":
+    console.log("Il Mango e la Papaia sono a €2.79 il chilo.");
+    break;
+  default:
+    console.log("Spiacenti, abbiano terminato " + tipidifrutta + ".");
+}
+console.log("C'è qualcos'altro che ti piace?");
+ +

Costrutti di gestione delle Eccezioni

+ +

Si può sollevare/generare un'eccezione attraverso l'istruzione throw e si possono gestire usando il costrutto try...catch.

+ + + +

Tipi di eccezione

+ +

Quasi ogni tipo di oggetto può essere usato per sollevare/generare un'eccezione JavaScript. Tuttavia non tutti gli oggetti utili a questo scopo sono creati in modo eguale. Mentre è abbastanza comune usare numeri o stringhe per indicare un errore, è più efficace usare uno dei tipi di eccezione specificatamente creati a questo scopo:

+ + + +

Istruzione throw

+ +

Si usa l'istruzione throw per sollevare/generare un'eccezione. Quando si genera un'eccezione va specificata un'espressione che produca un valore da usarsi come eccezione:

+ +
throw espressione;
+
+ +

Si può usare una qualsiasi espressione con l'istruzione throw e non solamente espressioni di un certo tipo. Il seguente pezzo di codice lo dimostra:

+ +
throw "Errore2";  // tipo String
+throw 42;         // tipo Number
+throw true;       // tipo Boolean
+throw {toString: function() { return "Sono un oggetto!"; } };
+
+ +
Note: Si può specificare un oggetto quando si genera un'eccezione. Si può poi far riferimento alle proprietà dell'oggetto nel blocco catch. Il seguente esempio crea un oggetto myUserException del tipo UserException e lo usa nell'istruzione throw.
+ +
// Crea un oggetto di tipo UserException
+function UserException(messaggio) {
+  this.message = messaggio;
+  this.name    = "UserException";
+}
+
+// Sovrascrive il metodo toString() affinché l'oggetto
+// dia una descrizione di se stesso al momento di usarlo come stringa.
+// (e.g. come messaggio nella console degli errori)
+UserException.prototype.toString = function() {
+  return this.name + ': "' + this.message + '"';
+}
+
+// Crea un'istanza dell'oggetto e lo usa nell'istruzione throw
+throw new UserException("Valore troppo alto!);
+ +

Costrutto try...catch (... finally)

+ +

Il costrutto try...catch racchiude un blocco di istruzioni, che potrebbero generare un'eccezione, e specifica uno o più azioni per gestire l'eccezione che potrebbe essere sollevata. Se viene sollevata un'eccezione il costrutto try...catch la cattura.

+ +

Il costrutto try...catch è costituito da un blocco try, che contiene a sua volta uno o più istruzioni, e da al più (vedi nota più sotto) un blocco catch, contenenti istruzioni per gestire l'eccezione che eventulmente sarà sollevata all'interno del blocco try.  Cioè si vorrebbe che il blocco try fosse eseguito senza errori, ma se non fosse possibile si vuole che l'esecuzione passi al blocco catch. Se un'istruzione contenuta nel blocco (o in una funzione chiamata all'interno del blocco) try genera un'eccezione, il controllo passa immediatamente al blocco catch. Se nessuna eccezione è sollevata all'interno del blocco try, il blocco catch è semplicemente ignorato. Il blocco finally (opzionale se c'è il blocco catch, ma necessario se manca quest'utimo) è eseguito subito dopo l'esecuzione dei blocchi try/catch, ma prima di una qualsiasi istruzione che segua gli stessi try...catch...finally.

+ +
+

In realtà il browser Firefox è in grado di suppostare i blocchi catch condizionati, oltre quello incondizionato, rendendo virtualmeente illimitata la definizione di più di un blocco catch per uno stesso blocco try. Tuttavia questa caratteristica non è standard e se ne scoraggia l'uso, si veda a proposito la referenza {{jsxref("Statements/try...catch", "try...catch")}}.

+
+ +

L'esempio che segue usa il costrutto di try...catch. L'esempio chiama una funzione che ritorna il nome del mese estratto da un array grazie al parametro mo passato alla funzione. Se il valore passato non corrispondesse al numero di mese consentito (tra 1 e 12), un'eccezione verrebbe sollevata col valore "numeroMeseNonValido" e il blocco catch assegnerebbe alla variabile nomeDelMese il vaore di "sconoscuto".

+ +
function getNomeDelMese(mo) {
+  mo = mo - 1; // Sistema il numero del mese (1 = Gen, 12 = Dic)
+  var mesi = ["Gen","Feb","Mar","Apr","Mag","Giu","Lug",
+                "Ago","Set","Ott","Nov","Dic"];
+  if (mesi[mo]) {
+    return mesi[mo];
+  } else {
+    throw "numeroMeseNonValido"; //l'istruzione throw è usata qui
+  }
+}
+
+try { // blocco try
+  nomeDelMese = getNomeDelMese(mese); // la funzione potrebbe sollevare un'eccezione
+}
+catch (eccezione) {
+  nomeDelMese = "sconosciuto";
+  logDegliErrori(eccezione); // Passa l'eccezione a un gestore -> una propria funzione
+
+ +

Il blocco catch

+ +

Si può usare il blocco catch per gestire le eccezioni che possono essere generate nel blocco try.

+ +
catch (catchID) {
+  // istruzioni
+}
+
+ +

Il blocco catch viene specificato un identificatore (catchID nel precedente esempio) che conterrà il valore specificato nell'istruzione throw. Si può usare questo identificatore per ottenere informazione ulteriori circa l'eccezione che è stata generata. JavaScript crea questo identificatore quando si entra nel blocco catch. L'identificatore è valido solo per la durata in esecuzione del blocco catch stesso, infatti usciti dal blocco catch termina la sua esistenza e non è più disponibile.

+ +

Per esempio, il seguente codice solleva un'eccezione. Quando l'eccezione si realizza il controllo passa al blocco catch.

+ +
try {
+  throw "miaEccezione"; // genera una eccezione
+}
+catch (eccezione) { // "eccezione" è l'identificatore con conterrà
+  // l'oggetto usato nell'istruzione thrown, in questo caso la stringa "miaEccezione"
+
+  // istruzioni che gestiscono l'eccezione
+  gestisciErrori(eccezione); // passa l'oggetto eccezione al gestore
+}
+
+ +

Il blocco finally

+ +

Il blocco finally contiene istruzioni che vengono eseguite subito dopo i blocchi try ed eventualmente catch, ma prima di ogni altra istruzione che segua il costrutto try...catch...finally. Il blocco finally è eseguito indipendentemente dal fatto che un'eccezione sia o meno generata. Se un'eccezione viene sollevata le istruzioni nel blocco finally saranno eseguite anche se il blocco catch corrispondente la gestisce.

+ +

Si può usare il blocco finally per permettere agli script di terminare elegantemente in presenza di un'eccezione, ad esempio, se si deve liberare una risorsa che lo script trattiene. Il seguente esempio apre un file e lo usa (JavaScript lato server permette di accedere al file system). Se si solleva un'eccezione mentre il file è aperto il blocco finally chiude il file prima che lo script termini/fallisca.

+ +
apriMioFile();
+try {
+  ScriviMioFile(dati); //Qui si può verificare un'eccezione/errore
+} catch(e) {
+  gestisciErrore(e); // Se avviene un errore lo si gestisce
+} finally {
+  chiudiMioFile(); // chiude comunque la risorsa
+}
+
+ +

Se il blocco finally ritorna un valore questo diviene il valore ritornato dall'intero costrutto try-catch-finally a dispetto di qualsiasi valore eventualmente ritornato dai blocchi try/catch:

+ +
function f() {
+  try {
+    console.log(0);
+    throw "fasulla";
+  } catch(e) {
+    console.log(1);
+    return true; // quasta istruzione di ritorno è sospesa
+                 // finché il blocco finally non termina
+    console.log(2); // istruzione non raggiungibile
+  } finally {
+    console.log(3);
+    return false; // sovrascrive il precedente "return"
+    console.log(4); // istruzione non raggiungibile
+  }
+  // "return false" è eseguito ora
+  console.log(5); // istruzione non raggiungibile
+}
+f(); // nel log a console troviamo stampato: 0, 1, 3 e false
+
+ +

La sovrascrittura dei valori di ritorno, da parte del blocco finally, colpisce anche le eccezioni generate e/o ri-generate dentro il blocco catch:

+ +
function f() {
+  try {
+    throw "fasulla";
+  } catch(e) {
+    console.log('catturata l\'eccezione interna "fasulla"');
+    throw e; // Quasta istruzione throw è sospesa
+             // finché il blocco finally non termina
+  } finally {
+    return false; // sovrascrive il precedente "throw"
+  }
+  // "return false" è eseguita ora
+}
+
+try {
+  f();
+} catch(e) {
+  // Questo blocco non sarà mai raggiunto in quanto l'istruzione
+  // throw dentro il blocco catch (vedi più sopra) è sovrascritta
+  // dal return della clausola finally
+  console.log('catturata l\'eccezione esterna "fasulla"');
+}
+
+// OUTPUT
+// catturata l'eccezione interna "fasulla"
+ +

try...catch innestati

+ +

Si possono annidare try...catch. Se un blocco try...catch interno non ha il blocco catch (in questo caso è d'obbligo che ci sia il blocco finally, anche vuoto, altrimenti si ha un errore sintattico), il blocco catch, del costrutto try...catch che lo racchiude, catturerà l'eventuale eccezione.

+ +
try{// try-catch esterno
+  try{
+   // try-finally interno
+    throw "eccezione fasulla";
+  }
+  // Manca il blocco catch, ma deve esserci il blocco finally
+  finally{
+    // vuoto
+  }
+}
+catch(e){
+  // Viene catturata l'eccezione sollevata dal blocco più interno
+  console.log("cattura esterna: " + e);
+}
+
+//nella console sarà stampato: "cattura esterna: eccezione fasulla"
+ +

Utilizzo degli oggetti Error

+ +

A seconda del tipo di errore se si è in grado di usare le proprietà 'name' e 'message' si può avere un messaggio più ricco. 'name' fornisce la classe generale dell'Error (e.g., 'DOMException' o 'Error'), mentre 'message' generalmente fornisce un messaggio più conciso rispetto al convertire l'oggetto corrispondente all'errore in una stringa.

+ +

Se si crea una propria eccezione affiché ci si avvantaggi di queste proprietà (come nel caso, ad esempio, del blocco catch che non discrimini tra l'oggetto rappresentante la propria eccezione e quello di sistema) si può usare il costruttore dell'oggetto Error:

+ +
function faiQualcosaSoggettaAdErrore () {
+  if (codiceCheProduceUnErrore()) {
+    throw (new Error('Il Messaggio'));
+  } else {
+    faiQualcosaPerOttenereUnEorreDiJavascript();
+  }
+}
+....
+try {
+  faiQualcosaSoggettaAdErrore();
+} catch (e) {
+  console.log(e.name);    // Scrive a console: 'Error'
+  console.log(e.message); // Scrive a console: 'Il Messaggio' o un messaggio di errore di JavaScript)
+}
+ +

I Promise

+ +

A partire da ECMAScript2015, JavaScript acquisisce il supporto agli oggetti {{jsxref("Promise")}} permettendo di controllare l'esecuzione di operazioni in modo differito e asincrono.

+ +

Un Promise può essere in uno di questi stati:

+ + + +

+ +

Caricare un'immagine con XHR

+ +

Un esempio di semplice utilizzo di un Promise e XMLHttpRequest per caricare un'immagine è disponibile nel repository promise-test di MDN GitHub. Si può anche vedere in azione. Ogni passo  è commentato e ti permette di seguire il Promise e l'architettura XHR da vicino. Qui, invece, la versione non commentata che mostra l'utilizzo del Promise per darti un'idea del suo funzionamento:

+ +
function caricaImmagine(url) {
+  return new Promise(function(resolve, reject) {
+    var request = new XMLHttpRequest();
+    request.open('GET', url);
+    request.responseType = 'blob';
+    request.onload = function() {
+      if (request.status === 200) {
+        resolve(request.response);
+      } else {
+        reject(Error('L\'immagine non è stata caricata con successo; codice di errore:'
+                     + request.statusText));
+      }
+    };
+    request.onerror = function() {
+      reject(Error('C\'è stato un errore di connessione'));
+    };
+    request.send();
+  });
+}
+ +

Per informazioni più dettagliate si veda la pagina di riferimento relativa al {{jsxref("Promise")}}.

+ +
{{PreviousNext("Web/JavaScript/Guide/Grammar_and_types", "Web/JavaScript/Guide/Loops_and_iteration")}}
diff --git a/files/it/web/javascript/guide/details_of_the_object_model/index.html b/files/it/web/javascript/guide/details_of_the_object_model/index.html new file mode 100644 index 0000000000..1e2d4dc74f --- /dev/null +++ b/files/it/web/javascript/guide/details_of_the_object_model/index.html @@ -0,0 +1,727 @@ +--- +title: Dettagli del modello a oggetti +slug: Web/JavaScript/Guida/Dettagli_Object_Model +tags: + - Guide + - Intermediate + - JavaScript +translation_of: Web/JavaScript/Guide/Details_of_the_Object_Model +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Working_with_Objects", "Web/JavaScript/Guide/Iterators_and_Generators")}}
+ +
+

Il contenuto di questo articolo è in discussione. Lascia un feedback e aiutaci a rendere migliore questa pagina: {{bug(1201380)}}.

+
+ +

JavaScript è un linguaggio ad oggetti basato su prototipi, piuttosto che sulle classi. A causa di questa diversa base, può essere meno evidente come JavaScript permette di creare gerarchie di oggetti e di avere l'ereditarietà delle proprietà e dei loro valori. Questo articolo cerca di chiarire questo aspetto.

+ +

Questo capitolo presuppone una certa familiarità con JavaScript e con l'uso delle funzioni per la creazione di semplici oggetti.

+ +

Linguaggi class-based vs. linguaggi prototype-based

+ +

I linguaggi ad oggetti basati su classi, come Java e C++, si basano su due entità distinte: le classi (classes) e le istanze (instances).

+ + + +

Un linguaggio basato su prototipi, come JavaScript, non fa questa distinzione: ha solo oggetti. Introduce la nozione di oggetto prototipo (prototypical object), un oggetto usato come modello da cui prendere le proprietà iniziali per un nuovo oggetto. Ogni oggetto può specificare le sue proprietà, anche quando viene creato o in fase di esecuzione.Inoltre, ogni oggetto può essere associato ad un altro oggetto come prototipo, consentendo al secondo oggetto di condividere le proprietà del primo.

+ +

Definizione di una classe

+ +

Nei linguaggi basati su classi, le classi vengono definite in class definition separate. In queste definizioni è possibile specificare metodi speciali, chiamari costruttori (constructors), per creare istanze della classe. Un costruttore può specificare i valori iniziali per le proprietà dell'istanza ed eseguire altre elaborazioni adatte al momento della creazione. Per creare le istanze di una classe si utilizza l'operatore new associato al metodo costruttore.

+ +

JavaScript segue un modello simile, ma non prevede la definizione della classe separata dal costruttore. Invece, per creare oggetti con un particolare set di proprietà e valori si definisce una funzione costruttore. Ogni funzione JavaScript può essere usata come costruttore. Per creare un nuovo oggetto si utilizza l'operatore new associato a una funzione costruttore.

+ +

Sottoclassi e ereditarietà

+ +

In un linguaggio basato su classi, si crea una gerarchia tra le classi attraverso le definizioni delle classi stesse. All'interno della definizione di una classe è possibile specificare che la nuova classe è una sottoclasse (subclass) di una classe esistente. La sottoclasse eredita tutte le proprietà della superclasse e può inoltre aggiungere nuove proprietà o modificare quelle ereditate. Per esempio, assumiamo che la classe Employee include solo le proprietà name e dept, e Manager è una sottoclasse di Employee che aggiunge la proprietà reports. In questo caso, un'istanza della classe Manager avrà tutte e tre le proprietà: name, dept, e reports.

+ +

JavaScript implementa l'ereditarietà permettendo di associare un oggetto prototipo ad ogni funzione costruttore. Quindi, è possibile ricreare esattamente l'esempio visto in precedenza, ma usando una terminologia leggermente diversa. Innanzitutto  si definisce la funzione costruttore Employee, specificando le proprietà name e dept. In seguito, si definisce la funzione costruttore Manager, chiamando il costruttore Employee e specificando la proprietà reports. Infine, si assegna a un nuovo oggetto derivato da Employee.prototype come il prototipo per la funzione costruttore Manager. Quando si crea un nuovo Manager, questo eredita le proprietà name e dept dall'oggetto Employee.

+ +

Aggiungere e rimuovere proprietà

+ +

Nei linguaggi basati su classi, una classe viene solitamente creata in fase di compilazione mentre le istanze possono essere create in fase di compilazione o in fase di esecuzione. Non è possibile cambiare il numero o il tipo di proprietà di una classe dopo che questa è stata definita. In JavaScript in fase di esecuzione si possono aggiungere o rimuovere proprietà a qualunque oggetto. Se si aggiunge una proprietà a un oggetto che è usato come prototipo per un gruppo di oggetti, anche gli oggetti del gruppo ereditano la nuova proprietà.

+ +

Riepilogo delle differenze

+ +

La tabella seguente fornisce un breve riepilogo di alcune di queste differenze. Il resto di questo capitolo descrive nel detteglio l'uso in JavaScript di costruttori e prototipi per creare una gerarchia di oggetti e lo confronta con la procedura che si userebbe in Java.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Confronto tra il sistema di oggetti basato su classi (Java) e il sistema di oggetti basato su prototipi (JavaScript)
Class-based (Java)Prototype-based (JavaScript)
Classi e istanze sono entità separate.Tutti gli oggetti possono ereditare da un altro oggetto.
Definire una classe con una definizione; istanziare una classe con un metodo costruttoreDefinire e creare una collezione di oggetti con una funzione costruttore.
Creare un singolo oggetto con l'operatore new.Uguale.
Costruire una gerarchia di oggetti usando la definizione di classe per definire le sottoclassi di classi esistenti.Costruire una gerarchia di oggetti assegnando un oggetto come prototipo associato a una funzione costruttore.
Ereditare le proprietà seguendo la catena delle classi.Ereditare le proprietà seguendo la catena dei prototipi.
La definizione di classe specifica tutte le proprietà di tutte le istanze della classe. Non è possibile aggiungere proprietà dinamicamente durante l'esecuzione.La funzione costruttore o il prototipo specificano un set iniziale di proprietà. È possibile aggiungere o rimuovere dinamicamente proprietà ai singoli oggetti o all'intero gruppo di oggetti.
+ +

L'esempio 'dipendente'

+ +

Il resto di questo capitolo usa la gerarchia dei dipendenti mostrata nella figura seguente.

+ +
+
+

Una semplice gerarchia con gli oggetti seguenti:

+ +

+
+ +
+
    +
  • Employee ha le proprietà name (il cui valore di default è una stringa vuota) e dept (il cui valore di default è "general").
  • +
  • Manager è basato su Employee. Aggiunge la proprietà reports  (il cui valore di default è un array vuoto, destinato a contenere una serie di oggetti Employee).
  • +
  • WorkerBee è anch'esso basato su Employee. Aggiunge la proprietà projects (il cui valore di default è un array vuoto, destinato a contenere una serie di stringhe).
  • +
  • SalesPerson è basato su WorkerBee. Aggiunge la proprietà quota (il cui valore di default è 100). Sovrascrive inoltre la proprietà dept con il valore "sales", che indica che tutti i venditori si trovano nello stesso dipartimento.
  • +
  • Engineer è basato su WorkerBee. Aggiunge la proprietà machine (il cui valore di default è una stringa vuota) e sovrascrive la proprietà dept con il valore "engineering".
  • +
+
+
+ +

Creazione della gerarchia

+ +

Ci sono diversi modi per definire una funzione costruttore appropriata per implementare la gerarchia dei dipendenti. Il modo scelto per definirli dipende molto da cosa si vuole riuscire a fare nella propria applicazione.

+ +

Questa sezione mostra come usare definizioni molto semplici (e relativamente rigide) per dimostrare come far funzionare l'ereditarietà. In queste definizioni, quando si crea un oggetto non è possibile specificare il valore di nessuna proprietà. L'oggetto creato avrà semplicemente i valori di default, che potranno essere cambiati in un secondo momento.

+ +

In una applicazione reale, probabilmente si vorranno definire dei costruttori che permettono di impostare i valori delle proprietà mentre si crea un oggetto (per maggiori informazioni si veda la sezione Costruttori più flessibili). Per adesso, queste semplici definizioni dimostrano come le proprietà vengono ereditate.

+ +

Le seguenti definizioni Java e JavaScript di Employee sono simili. L'unica differenza è che in Java si ha la necessità di specificare il tipo di ogni proprietà (questo è dovuto al fatto che Java è un linguaggio fortemente tipizzato mentre JavaScript è un linguaggio a tipizzazione dinamica.

+ +
+

JavaScript

+ +
function Employee() {
+  this.name = "";
+  this.dept = "general";
+}
+
+ +

Java

+ +
public class Employee {
+   public String name = "";
+   public String dept = "general";
+}
+
+
+ +

Le definizioni di Manager e WorkerBee mostrano la differenza nel modo di specificare l'oggetto seguente che si trova più in alto nella catena di ereditarietà. In JavaScript si aggiunge un'istanza prototipo come valore della proprietà prototype della funzione costrutore. È possibile farlo in qualsiasi momento dopo aver definito il costruttore. In Java, si specifica la superclasse all'interno della definizione della classe. Non è possibile cambiare la superclasse all'esterno della definizione.

+ +
+

JavaScript

+ +
function Manager() {
+  Employee.call(this);
+  this.reports = [];
+}
+Manager.prototype = Object.create(Employee.prototype);
+
+function WorkerBee() {
+  Employee.call(this);
+  this.projects = [];
+}
+WorkerBee.prototype = Object.create(Employee.prototype);
+
+ +

Java

+ +
public class Manager extends Employee {
+   public Employee[] reports = new Employee[0];
+}
+
+
+
+public class WorkerBee extends Employee {
+   public String[] projects = new String[0];
+}
+
+
+
+
+ +

Le definizioni di Engineer e SalesPerson creano oggetti che discendono da  WorkerBee, e quindi da Employee. Un oggetto di questo tipo ha le proprietà di tutti gli oggetti che si trovano sopra di esso nella catena. Inoltre, queste definizioni sovrascrivono il valore ereditato delle proprietà  dept con nuovi valori specifici per questi oggetti.

+ +
+

JavaScript

+ +
function SalesPerson() {
+   WorkerBee.call(this);
+   this.dept = "sales";
+   this.quota = 100;
+}
+SalesPerson.prototype = Object.create(WorkerBee.prototype);
+
+function Engineer() {
+   WorkerBee.call(this);
+   this.dept = "engineering";
+   this.machine = "";
+}
+Engineer.prototype = Object.create(WorkerBee.prototype);
+
+ +

Java

+ +
public class SalesPerson extends WorkerBee {
+   public String dept = "sales";
+   public double quota = 100.0;
+}
+
+
+public class Engineer extends WorkerBee {
+   public String machine;
+   public String dept = "engineering";
+   public String machine = "";
+}
+
+
+
+ +

Usando queste definizioni è possibile creare istanze di questi oggetti che ricevono i valori di default delle loro proprietà. La figura seguente illustra l'utilizzo di queste definizioni JavaScript per creare nuovi oggetti e mostra i valori delle diverse proprietà per questi nuovi oggetti.

+ +
+

Nota: Il termine istanza ha uno specifico significato tecnico nei linguaggi basati su classi. In questi linguaggi, un'istanza è una singola istanziazione di una classe ed è fondamentalmente differente dala classe. In JavaScript, "istanza" non ha questo significato tecnico perché JavaScript non ha questa differenza tra classi e istanze. Tuttavia, parlando di JavaScript, "istanza" può essere usato in modo informale per riferirsi a un oggetto creato usando una particolare funzione costruttore. Quindi, in questo esempio, è possibile dire che jane è un'istanza di Engineer. Allo stesso modo, sebbene i termini genitore  (parent), figlio (child), antenato (ancestor) e discendente (descendant) non hanno un significato conenzionale in JavaScript, possono essere usati in modo informale per riferirsi a oggetti che si trovano più o meno in alto nella catena dei prototipi.

+
+ +

Creazione di oggetti con definizioni semplici

+ +
+

Gerarchia degli oggetti

+ +

La gerarchia seguente è creata usando il codice sulla destra.

+ +

+ +

 

+ +

singoli oggetti

+ +
var jim = new Employee;
+// jim.name is ''
+// jim.dept is 'general'
+
+var sally = new Manager;
+// sally.name is ''
+// sally.dept is 'general'
+// sally.reports is []
+
+var mark = new WorkerBee;
+// mark.name is ''
+// mark.dept is 'general'
+// mark.projects is []
+
+var fred = new SalesPerson;
+// fred.name is ''
+// fred.dept is 'sales'
+// fred.projects is []
+// fred.quota is 100
+
+var jane = new Engineer;
+// jane.name is ''
+// jane.dept is 'engineering'
+// jane.projects is []
+// jane.machine is ''
+
+
+ +

Proprietà degli oggetti

+ +

Questa sezione spiega come gli oggetti ereditano le proprietà da altri oggetti presenti nella catena dei prototipi e cosa succede quando viene aggiunta una proprietà in fase di esecuzione.

+ +

Ereditare le proprietà

+ +

Supponiamo di creare un nuovo oggetto WorkerBee chiamato mark con l'istruzione seguente:

+ +
var mark = new WorkerBee;
+
+ +

Quando JavaScript vede l'operatore new, crea un nuovo oggeto generico e lo passa come valore della parola chiave this nella funzione costruttore WorkerBee. La funzione costruttore imposta esplicitamente il valore della proprietà projects e implicitamente il valore della proprietà interna __proto__ uguale al valore WorkerBee.prototype. (Il nome di questa proprietà ha due underscores iniziali e due finali). La proprietà __proto__ determina la catena di prototipi usata per restituire i valori delle proprietà. Una volta che queste proprietà sono impostate, JavaScript restituisce il nuovo oggetto e l'istruzione di assegnazione imposta la variabile mark per questo oggetto.

+ +

Questo processo non inserisce esplicitamente valori nell'oggetto mark (valori locali) per le proprietà che l'oggetto eredita dalla catena dei prototipi. Quando si richiede un valore di una proprietà, JavaScript prima controlla se il valore è presente nell'oggetto. Se c'è, viene restituito quel valore. Se il valore non è presente a livello locale, JavaScript controlla la catena dei prototipi (sfruttando la proprietà __proto__). Se un oggetto nella catena dei prototipi ha un valore per la proprietà, viene restituito. Se non viene trovata la proprietà, JavaScript risponde che l'oggetto non ha la proprietà cercata. In questo modo, l'oggetto mark ha le seguenti propietà con i rispettivi valori:

+ +
mark.name = "";
+mark.dept = "general";
+mark.projects = [];
+
+ +

L'oggetto mark eredita i valori per le proprietà name e dept dall'oggetto prototipo presente in mark.__proto__. Il costruttore WorkerBee assegna un valore locale per la proprietà projects. L'ereditarietà di proprietà e valori in JavaScript fnziona in questo modo. Alcune sottigliezze su questo processo sono trattate nella sezione Ereditare le proprietà (revisited).

+ +

Poiché questi costruttori non permettono di fornire valori specifici per una singola istanza, questa informazione è generica. I valori delle proprietà sono quelli di default condivisi da tutti i nuovi oggetti creati da WorkerBee. È oviamente possibile cambiare i valori di ognuna di queste proprietà. È quindi possibile assegnare informazioni specifice per mark nel modo seguente:

+ +
mark.name = "Doe, Mark";
+mark.dept = "admin";
+mark.projects = ["navigator"];
+ +

Aggiungere proprietà

+ +

In JavaScript, è possibile aggiungere proprietà a qualsiasi oggetto in fase di esecuzione. Non si è costretti ad usare solo le proprietà fornite dalla funzione costruttore. Per aggiungere una proprietà che sia specifica per un singolo oggetto, si deve assegnare il valore all'oggetto nel modo seguente::

+ +
mark.bonus = 3000;
+
+ +

Ora, l'oggetto markha una proprietà bonus, ma nessun altro WorkerBee ha questa proprietà.

+ +

Se si aggiunge una nuova proprietà a un oggetto che viene usato come prototipo per una funzione costruttore, la proprietà sarà aggiunta a tutti gli oggetti che ereditano le proprietà dal prototipo. Per esempio, è possibile aggiungere la proprietà specialty a tutti i dipendenti con l'istruzione seguente:

+ +
Employee.prototype.specialty = "none";
+
+ +

Non appena JavaScript esegue questa istruzione, anche l'oggetto mark avrà la proprietà specialty con il valore "none". La figura seguente mostra cosa succede qunado questa proprietà viene aggiunta al prototipo Employee e in seguito la si sovrascrive per il prototipo Engineer.

+ +


+ Aggiungere le proprietà

+ +

Costruttori più flessibili

+ +

Le funzioni costruttore mostrate finora non permettono di specificare i valori delle proprietà qunado viene creata un'istanza. Come in Java, è possibile fornire argomenti al costruttore per inizializzare i valori delle proprietà per le istanze. La figura seguente mostra un modo per farlo.

+ +


+ Specificare le proprietà in un costruttore, modo 1

+ +

La tabella seguente mostra le definizioni di questi oggetti in JavaScript e in Java.

+ +
+

JavaScript

+ +

Java

+
+ +
+
function Employee (name, dept) {
+  this.name = name || "";
+  this.dept = dept || "general";
+}
+
+ +

 

+ +

 

+ +

 

+ +

 

+ +
public class Employee {
+   public String name;
+   public String dept;
+   public Employee () {
+      this("", "general");
+   }
+   public Employee (String name) {
+      this(name, "general");
+   }
+   public Employee (String name, String dept) {
+      this.name = name;
+      this.dept = dept;
+   }
+}
+
+
+ +
+
function WorkerBee (projs) {
+
+ this.projects = projs || [];
+}
+WorkerBee.prototype = new Employee;
+
+ +

 

+ +

 

+ +
public class WorkerBee extends Employee {
+   public String[] projects;
+   public WorkerBee () {
+      this(new String[0]);
+   }
+   public WorkerBee (String[] projs) {
+      projects = projs;
+   }
+}
+
+
+ +
+
+function Engineer (mach) {
+   this.dept = "engineering";
+   this.machine = mach || "";
+}
+Engineer.prototype = new WorkerBee;
+
+ +

 

+ +

 

+ +
public class Engineer extends WorkerBee {
+   public String machine;
+   public Engineer () {
+      dept = "engineering";
+      machine = "";
+   }
+   public Engineer (String mach) {
+      dept = "engineering";
+      machine = mach;
+   }
+}
+
+
+ +

Queste definizioni JavaScript usano un linguaggio speciale per impostare i valori di default:

+ +
this.name = name || "";
+
+ +

In JavaScript l'operatore logico OR (||) valuta il suo primo argomento. Se questa espressione può essere convertita a true, l'operatore restituisce il primo argomento. Altrimenti l'operatore restituisce il valore del secondo argomento. Quindi, questa linea di codice verifica se name ha un valore utile per la proprietà name. Se ce l'ha, imposta this.name a questo valore. Altrimenti, imposta this.name a una stringa vuota. Questo capitolo usa questo linguaggio per brevità, comunque può disorientare a prima vista.

+ +
+

Nota: Potrebbe non funzionare come atteso se la funzione costruttore è chiamata con un argomento che converte a false (come ad esempio 0 (zero) o una stringa vuota ("")). In questo caso verrà scelto il valore di default.

+
+ +

Con queste definizioni, quando si crea un'istanza di un oggetto, è possibile specificare i valori per le proprietà definite localmente. Per creare un nuovo Engineer è possibile utilizzare l'espressione seguente:

+ +
var jane = new Engineer("belau");
+
+ +

Le proprietà di Jane sono ora:

+ +
jane.name == "";
+jane.dept == "engineering";
+jane.projects == [];
+jane.machine == "belau"
+
+ +

È da notare che con queste definizioni non è possibile specificare una valore iniziale per le proprietà ereditate, come ad esempio name. Se si desidera specificare un valore iniziale per una proprietà ereditata, in JavaScript è necessario aggiungere ulteriore codice alla funzione costruttore.

+ +

Finora, la funzione costruttore ha creato un oggetto generico e poi ha specificato proprietà locali e valori per il nuovo oggetto. È possibile fare in modo che il costruttore aggiunga più proprietà chiamando direttamente la funzione costruttore per un oggetto che si trova a un livello più alto nella catena dei prototipi. La figura seguente mostra queste nuove definizioni.

+ +


+ Specificare le proprietà in un costruttore, modo 2

+ +

Guardiamo nel dettaglio una di queste definizioni. Ecco la nuova definizione per il costruttore Engineer:

+ +
function Engineer (name, projs, mach) {
+  this.base = WorkerBee;
+  this.base(name, "engineering", projs);
+  this.machine = mach || "";
+}
+
+ +

Supponiamo di creare un nuovo oggetto Engineer nel modo seguente:

+ +
var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
+
+ +

JavaScript segue questa procedura:

+ +
    +
  1. L'operatore new crea un oggetto generico e imposta il valore Engineer.prototype per la sua proprietà __proto__.
  2. +
  3. L'operatore new passa il nuovo oggetto come valore della parola chiave this nella funzione costruttore Engineer.
  4. +
  5. Il costruttore crea una nuova proprietà per l'oggetto chiamata base e assegna il valore del costruttore WorkerBee alla proprietà base. Questo rende il costruttore WorkerBee un metode dell'oggetto Engineer. Il nome della proprietà base non è peculiare. È possibile usare qualsiasi nome per la proprietà; base è semplicemente evocativo dello scopo.
  6. +
  7. Il costruttore chiama il metodo base, passando come suoi argomenti due degli argomenti passati al costruttore ("Doe, Jane" e ["navigator", "javascript"]) e anche la stringa "engineering". Usando esplicitamente "engineering" nel costruttore indica che tutti gli oggetti Engineer hanno lo stesso valore per la proprietà dept ereditata, e questo valore sovrascrive il valore ereditato dal costruttore Employee.
  8. +
  9. Poiché base è un metodo di Engineer, all'interno della chiamata di base, JavaScript aggiunge la parola chiave this all'oggetto creato al passaggio 1. In questo modo, la funzione WorkerBee a sua volta passa gli argomenti "Doe, Jane" e "engineering" alla funzione costruttore Employee. Dopo l'esecuzione della funzione costruttore Employee, la funzione WorkerBee utilizza l'argomento rimanente per impostare la proprietà projects.
  10. +
  11. Dopo l'esecuzione del metodo base, il costruttore Engineer inizializza la proprietà machine dell'oggetto al valore "belau".
  12. +
  13. Dopo l'esecuzione del costruttore, JavaScript assegna il nuovo oggetto alla variabile jane.
  14. +
+ +

Avendo chiamato il costruttore WorkerBee dall'interno del costruttore Engineer, si potrebbe pensare di aver impostato in modo corretto l'ereditarietà per gli oggetti Engineer. Questo non è il caso. Chiamare il costruttore WorkerBee assicura che un oggetto Engineer venga creato con le proprietà specificate in tutte le funzioni costruttore che sono chiamate. Però, se in un secondo momento vengono aggiunte proprietà ai prototipi Employee o WorkerBee, queste proprietà non saranno ereditate dall'oggetto Engineer. Per esempio, se si considera il codice seguente:

+ +
function Engineer (name, projs, mach) {
+  this.base = WorkerBee;
+  this.base(name, "engineering", projs);
+  this.machine = mach || "";
+}
+var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
+Employee.prototype.specialty = "none";
+
+ +

L'oggetto jane non eredita la proprietà specialty. È comunque necessario impostare esplicitamente il prototipo per garantire l'ereditarietà dinamica. Se si considera invece l'esempio seguente:

+ +
function Engineer (name, projs, mach) {
+  this.base = WorkerBee;
+  this.base(name, "engineering", projs);
+  this.machine = mach || "";
+}
+Engineer.prototype = new WorkerBee;
+var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
+Employee.prototype.specialty = "none";
+
+ +

Adesso il valore per l'oggetto jane della proprietà specialty è "none".

+ +

Un altro modo per ereditare le proprietà è l'utilizzo dei metodi call() e apply(). Gli esempi sottostanti si equivalgono:

+ +
+
function Engineer (name, projs, mach) {
+  this.base = WorkerBee;
+  this.base(name, "engineering", projs);
+  this.machine = mach || "";
+}
+
+ +
function Engineer (name, projs, mach) {
+  WorkerBee.call(this, name, "engineering", projs);
+  this.machine = mach || "";
+}
+
+
+ +

L'utilizzo del metodo call() costituisce un'implementazione più pulita poiché la proprietà base non è più necessaria.

+ +

Ereditare le proprietà (revisited)

+ +

Le sezioni precedenti descrivono come i costruttori e i prototipi consentono di avere gerarchia ed ereditarietà in JavaScript. Questa sezione espone alcune sottiglienzze che non erano necessariamente evidenti nelle discussioni precedenti.

+ +

Valori locali vs. valori ereditati

+ +

Quando si accede a una proprietà di un oggetto, JavaScript esegue i seguenti passaggi, come descritto in precedenza in questo capitolo:

+ +
    +
  1. Verifica se il valore è presente a livello locale. Se c'è, restituisce quel valore.
  2. +
  3. Se non è presente, verifica la catena dei prototipi (usando la proprietà __proto__).
  4. +
  5. Se un oggetto nella catena dei prototipi ha un valore per la proprietà specificata, restituisce quel valore.
  6. +
  7. Se la proprietà non viene trovata, l'oggetto non ha la proprietà.
  8. +
+ +

Il risultato di questo processo dipende da come sono stati definiti gli elementi. L'esempio iniziale aveva queste definizioni:

+ +
function Employee () {
+  this.name = "";
+  this.dept = "general";
+}
+
+function WorkerBee () {
+  this.projects = [];
+}
+WorkerBee.prototype = new Employee;
+
+ +

Con queste definizioni, si supponga di creare amy come un'istanza di WorkerBee con la seguente istruzione:

+ +
var amy = new WorkerBee;
+
+ +

L'oggetto amy ha una proprietà locale, projects. I valori per le proprietà name e dept non sono specifici per amy e quindi derivano dalla proprietà __proto__ dell'oggetto amy. Quindi, amy ha i seguenti valori:

+ +
amy.name == "";
+amy.dept == "general";
+amy.projects == [];
+
+ +

Ora si supponga di cambiare il valore della proprietà name nel prototipo associato con Employee:

+ +
Employee.prototype.name = "Unknown"
+
+ +

Ci si potrebbe aspettare che il nuovo valore si propaghi a tutte le istanze di Employee. Invece, non lo fa.

+ +

Quando si crea qualsiasi istanza dell'oggetto Employee, questa istanza riceve un valore locale per la proprietà name (la stringa vuota). Questo significa che quando si imposta il prototipo WorkerBee creando un nuovo oggetto Employee, WorkerBee.prototype avrà un valore locale per la proprietà name. Quindi, quando JavaScript legge la proprietà name dell'oggetto amy (istanza di WorkerBee), trova in WorkerBee.prototype il valore locale di questa proprietà. Pertanto non continua a cercare nella catena salendo a Employee.prototype.

+ +

Se si vuole cambiare il valore di una proprietà di un oggetto in fase di esecuzione e si vuole che il nuovo valore venga ereditato da tutti i discendenti dell'oggetto, non è possibile definire la proprietà all'interno della funzione costruttore dell'oggetto. Invece, si aggiunge la proprietà al prototipo associato al costruttore. Per esempio, assumiamo di cambiare il codice precedente con quello che segue:

+ +
function Employee () {
+  this.dept = "general";    // Note that this.name (a local variable) does not appear here
+}
+Employee.prototype.name = "";    // A single copy
+
+function WorkerBee () {
+  this.projects = [];
+}
+WorkerBee.prototype = new Employee;
+
+var amy = new WorkerBee;
+
+Employee.prototype.name = "Unknown";
+
+ +

In questo caso, il valore della proprietà name di amy diventa "Unknown".

+ +

Come mostra questo esempio, se si vogliono avere i valori di default per le proprietà dell'oggetto e si vuole avere la possibilità di cambiare questi valori in fase di esecuzione, si devono impostare le proprietà nel prototipo del costruttore, e non direttamente nella funzione costruttore.

+ +

Determinazione delle relazioni tra istanze

+ +

In JavaScript la ricerca delle proprietà (property lookup) controlla prima tra le proprietà specifiche dell'oggetto e, se il nome della proprietà non viene trovato, controlla la proprietà speciale __proto__. Il processo, chiamato "ricerca nella catena dei prototipi" (lookup in the prototype chain), continua ricorsivamente .

+ +

Quando un oggetto viene costruito, la proprietà speciale __proto__ viene impostata al valore della proprietà prototype del costruttore. L'espressione new Foo() crea un oggetto con __proto__ == Foo.prototype. Di conseguenza, le modifiche alle proprietà di Foo.prototype alterano la ricerca delle proprietà per tutti gli oggetti che sono stati creati con new Foo().

+ +

Ogni oggetto ha una proprietà __proto__ (ad eccezione di Object); ogni funzione ha una proprietà prototype. Quindi gli oggetti possono essere correlati ad altri oggetti attraverso una 'ereditarietà prototipale' (prototypal inheritance). È possibile verificare l'ereditarietà confrontando la proprietà __proto__ di un oggetto con l'oggetto prototype di una funzione. JavaScript fornisce una scorciatoia: l'operatore instanceof confronta un oggetto con una funzione e restituisce true se l'oggetto eredita dal prototipo della funzione. Per esempio,

+ +
var f = new Foo();
+var isTrue = (f instanceof Foo);
+ +

Per un esempio più dettagliato, supponiamo di avere lo stesso gruppo di definizioni visto nella sezione For a more detailed example, suppose you have the same set of definitions shown in Ereditare le proprietà. Creiamo un oggetto Engineer nel modo seguente:

+ +
var chris = new Engineer("Pigman, Chris", ["jsd"], "fiji");
+
+ +

Per questo oggetto, tutti gli enunciati seguenti sono veri:

+ +
chris.__proto__ == Engineer.prototype;
+chris.__proto__.__proto__ == WorkerBee.prototype;
+chris.__proto__.__proto__.__proto__ == Employee.prototype;
+chris.__proto__.__proto__.__proto__.__proto__ == Object.prototype;
+chris.__proto__.__proto__.__proto__.__proto__.__proto__ == null;
+
+ +

Dato ciò, è possibile scrivere una funzione instanceOf come segue:

+ +
function instanceOf(object, constructor) {
+   object = object.__proto__;
+   while (object != null) {
+      if (object == constructor.prototype)
+         return true;
+      if (typeof object == 'xml') {
+        return constructor.prototype == XML.prototype;
+      }
+      object = object.__proto__;
+   }
+   return false;
+}
+
+ +
+

Nota: L'implementazione vista sopra verifica se l'oggetto è di tipo "xml" per ovviare a una stranezza nel modo in cui gli oggetti XML sono rappresentati nelle versioni recenti di JavaScript. Per i dettagli essenziali si veda il {{ bug(634150) }}.

+
+ +

Se si utilizza la funzione instanceOf definita in precedenza, queste espressioni sono vere:

+ +
instanceOf (chris, Engineer)
+instanceOf (chris, WorkerBee)
+instanceOf (chris, Employee)
+instanceOf (chris, Object)
+
+ +

Ma l'espressione seguente è falsa:

+ +
instanceOf (chris, SalesPerson)
+
+ +

Informazioni globali nei costruttori

+ +

Quando vengono creati dei costruttori, è necessario essere scrupolosi se si impostano informazioni globali all'interno del costruttore. Per esempio, se si vuole che un ID univoco venga assegnato automaticamente a ogni nuovo Employee si potrebbe usare la definizione seguente:

+ +
var idCounter = 1;
+
+function Employee (name, dept) {
+   this.name = name || "";
+   this.dept = dept || "general";
+   this.id = idCounter++;
+}
+
+ +

Con questa definizione, quando viene creato un nuovo Employee, il costruttore assegna l'ID seguente e incrementa il contatore globale (idCounter). Così, se l'istruzione successiva è la seguente, l'ID di victoria sarà 1, l'ID di harry sarà 2:

+ +
var victoria = new Employee("Pigbert, Victoria", "pubs")
+var harry = new Employee("Tschopik, Harry", "sales")
+
+ +

Questa a prima vista potrebbe sembrare la procedura corretta. Tuttavia, il contatore globale idCounter viene incrementato ogni volta che viene creato un oggetto Employee, per qualsiasi scopo. Se viene creata l'intera gerarchia di oggetti Employee mostrata in questo capitolo, il costruttore Employee viene chiamato ogni volta che si definisce un prototipo. Supponiamo di avere il codice seguente:

+ +
var idCounter = 1;
+
+function Employee (name, dept) {
+   this.name = name || "";
+   this.dept = dept || "general";
+   this.id = idCounter++;
+}
+
+function Manager (name, dept, reports) {...}
+Manager.prototype = new Employee;
+
+function WorkerBee (name, dept, projs) {...}
+WorkerBee.prototype = new Employee;
+
+function Engineer (name, projs, mach) {...}
+Engineer.prototype = new WorkerBee;
+
+function SalesPerson (name, projs, quota) {...}
+SalesPerson.prototype = new WorkerBee;
+
+var mac = new Engineer("Wood, Mac");
+
+ +

Si assuma inoltre che le definizioni omesse abbiano la proprietà base e chiamino il costruttore che si trova al livello superiore nella catena dei prototipi. In questo caso, nel momento in cui viene creato l'oggetto mac, il valore di mac.id sarà 5.

+ +

A seconda dell'applicazione, può essere più o meno importante che il valore del contatore sia stato incrementato queste volte aggiuntive. Se interessa il valore esatto di questo contatore, una soluzione possibile può prevedere l'uso del costruttore seguente al posto di quello visto in precedenza:

+ +
function Employee (name, dept) {
+   this.name = name || "";
+   this.dept = dept || "general";
+   if (name)
+      this.id = idCounter++;
+}
+
+ +

Quando viene creata un'istanza di Employee che deve essere usata come prototipo, non vengono forniti argomenti al costruttore. Usando questa definizione del costruttore, quando non vengono inseriti argomenti, il costruttore non assegna un valore all'ID e non aggiorna il contatore. Quindi, affinché a un oggetto Employee venga assegnato un ID, è necesario specificare un nome per il dipendente. In questo esempio, l'ID di mac sarà 1.

+ +

JavaScript non supporta l'ereditarietà multipla

+ +

Alcuni linguaggi ad oggetti ammettono l'ereditarietà multipla. Ossia, un oggetto può ereditare proprietà e valori da oggetti genitori non correlati. Javascript non supporta l'ereditarietà multipla.

+ +

L'eredità dei valori delle proprietà si ha in fase di esecuzione quando JavaScript cerca attraverso la catena dei prototipo di un oggetto per trovare un valore. Poiché un oggetto ha un unico prototipo associato, JavaScript non può ereditare dinamicamente da più di una catena di prototipi.

+ +

In JavaScript, è possibile che una funzione costruttore chiami al suo interno diverse funzioni costruttore. Questo dà l'illusione dell'ereditarietà multipla. Per esempio consideriamo le istruzioni seguenti:

+ +
function Hobbyist (hobby) {
+   this.hobby = hobby || "scuba";
+}
+
+function Engineer (name, projs, mach, hobby) {
+   this.base1 = WorkerBee;
+   this.base1(name, "engineering", projs);
+   this.base2 = Hobbyist;
+   this.base2(hobby);
+   this.machine = mach || "";
+}
+Engineer.prototype = new WorkerBee;
+
+var dennis = new Engineer("Doe, Dennis", ["collabra"], "hugo")
+
+ +

Assumiamo inoltre che la definizione di WorkerBee sia quella usata in precedenza in questo capitolo. In questo caso, l'oggetto dennis avrà queste proprietà:

+ +
dennis.name == "Doe, Dennis"
+dennis.dept == "engineering"
+dennis.projects == ["collabra"]
+dennis.machine == "hugo"
+dennis.hobby == "scuba"
+
+ +

Quindi dennis riceve la proprietà hobby dal costruttore Hobbyist. Però, se in seguito si aggiunge una proprietà al prototipo del costruttore Hobbyist:

+ +
Hobbyist.prototype.equipment = ["mask", "fins", "regulator", "bcd"]
+
+ +

L'oggetto dennis non erediterà questa nuova proprietà.

+ +
{{PreviousNext("Web/JavaScript/Guide/Working_with_Objects", "Web/JavaScript/Guide/Iterators_and_Generators")}}
diff --git a/files/it/web/javascript/guide/functions/index.html b/files/it/web/javascript/guide/functions/index.html new file mode 100644 index 0000000000..4aca8d5a7b --- /dev/null +++ b/files/it/web/javascript/guide/functions/index.html @@ -0,0 +1,646 @@ +--- +title: Funzioni +slug: Web/JavaScript/Guida/Functions +translation_of: Web/JavaScript/Guide/Functions +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Loops_and_iteration", "Web/JavaScript/Guide/Expressions_and_Operators")}}
+ +
 
+ +

Le funzioni sono tra i blocchi di programmazione fondamentali in JavaScript. Una funzione è una procedura JavaScript — un gruppo di istruzioni ( statement ) che esegue un compito o calcola un valore. Per usare una funzione, occorre definirla, all'interno dello scope dal quale la si invocherà.

+ +

Vedi anche l'esaustivo capitolo della guida di riferimento, che tratta delle funzioni JavaScript, per avere maggiori dettagli.

+ +

Definire una funzione

+ +

Dichiarazioni di funzione

+ +

Una definizione di funzione ( o dichiarazione di funzione, o istruzione di funzione ) consiste della parola chiave function, seguita da:

+ + + +

Per esempio, il codice seguente definisce una funzione semplice chiamata square:

+ +
function square(number) {
+  return number * number;
+}
+
+ +

La funzione square riceve un argomento, chiamato number. La funzione contiene una sola istruzione che dice di restituire ( return ) l'argomento della funzione ( number ) moltiplicato per se stesso. L'istruzione return specifica il valore restituito dalla funzione.

+ +
return number * number;
+
+ +

I parametri primitivi ( quale un numero ) vengono passati alla funzione come valore; il valore è passato alla funzione, ma se la funzione cambia il valore del parametro, questo cambiamento non si riflette globalmente, o nella funzione chiamante ( la funzione che, eventualmente, ha invocato la funzione in esecuzione ).

+ +

Se, invece, alla funzione viene passato un oggetto ( un valore non-primitivo, come, ad esempio, un Array oppure un oggetto definito dall'utente ) come parametro e la funzione modifica le proprietà dell'oggetto, quella modifica sarà visibile anche fuori dalla funzione, come si può vedere dal seguente esempio:

+ +
function myFunc(theObject) {
+  theObject.make = "Toyota";
+}
+
+var mycar = {make: "Honda", model: "Accord", year: 1998};
+var x, y;
+
+x = mycar.make; // x gets the value "Honda"
+
+myFunc(mycar);
+y = mycar.make; // y gets the value "Toyota"
+                // (the make property was changed by the function)
+
+ +

Espressioni di funzione

+ +

Mentre la dichiarazione di funzione di cui sopra è, da un punto di vista sintattico, un'istruzione, le funzioni possono anche essere create da un'espressione di funzione. Una funzione di questo tipo può anche essere anonima; vale a dire, non deve avere un nome. Per esempio, la funzione square potrebbe essere stata definita come:

+ +
var square = function(number) { return number * number };
+var x = square(4) // x gets the value 16
+ +

Tuttavia, è possibile assegnare un nome alla funzione anche con l'espressione di funzione e quel nome potrà essere utilizzato all'interno della funzione, per riferirsi alla funzione stessa, oppure in un debugger, per identificare la funzione all'interno dello stack:

+ +
var factorial = function fac(n) { return n<2 ? 1 : n*fac(n-1) };
+
+console.log(factorial(3));
+
+ +

NB: l'oggetto console non è un oggetto standard. Non usatelo in un sito web, poichè potrebbe non funzionare correttamente. Per verificare il funzionamento dell'esempio precedente, usate, piuttosto:

+ +

           window.alert(factorial(3));

+ +

Le espressioni di funzione sono utili quando si vuole passare una funzione ad un'altra funzione, come argomento. Il prossimo esempio mostra una funzione map che viene definita e poi invocata, con una funzione anonima come primo parametro:

+ +
function map(f,a) {
+  var result = [], // Create a new Array
+      i;
+  for (i = 0; i != a.length; i++)
+    result[i] = f(a[i]);
+  return result;
+}
+
+ +

Il seguente codice:

+ +
map(function(x) {return x * x * x}, [0, 1, 2, 5, 10]);
+
+ +

restituisce [0, 1, 8, 125, 1000].

+ +

In JavaScript, una funzione può essere definita in base ad una condizione. Per esempio, la definizione di funzione seguente definisce la funzione myFunc solo se num è uguale a 0 ( zero ):

+ +
var myFunc;
+if (num == 0){
+  myFunc = function(theObject) {
+    theObject.make = "Toyota"
+  }
+}
+ +

Per definire una funzione, inoltre, è possibile usare il costruttore Function, per creare funzioni da una stringa, in runtime, in modo simile a eval().

+ +

Un metodo è una funzione che è una proprietà di un oggetto. Leggi di più sugli oggetti e sui metodi in Working with objects.

+ +

Chiamare ( invocare ) una funzione

+ +

Definire una funzione non significa eseguirla. Definire una funzione significa semplicemente darle un nome e specificare cosa fare quando la funzione viene chiamata ( invocata ). Chiamare una funzione significa eseguire le azioni specificate, utilizzando i parametri indicati. Per esempio, se definiamo la funzione square, possiamo chiamarla o invocarla nel modo seguente:

+ +
square(5);
+
+ +

Questa istruzione chiama la funzione, inviandole un argomento, il numero 5. La funzione esegue le sue istruzioni e restituisce il valore 25.

+ +

Le funzioni devono essere in scope quando vengono chiamate, ma la dichiarazione di funzione può anche apparire sotto la chiamata, nel codice sorgente, come nell'esempio seguente:

+ +
console.log(square(5));
+/* ... */
+function square(n) { return n*n }
+
+ +

Lo scope di una funzione è la funzione nella quale è stata dichiarata, oppure l'intero programma se la dichiarazione è stata fatta al livello più alto, non annidata in alcun altro blocco di programmazione.

+ +
+

Nota: l'ultimo esempio funziona solo quando la funzione viene definita utilizzando la sintassi usata nell'esempio ( function funcName(){} ). Il codice seguente, invece, non funzionerà:

+
+ +
console.log(square(5));
+square = function (n) {
+  return n * n;
+}
+
+ +

Gli argomenti di una funzione non sono limitati alle stringhe testuali e ai numeri. È possibile passare anche interi oggetti ad una funzione. La funzione show_props() (definita in Working with objects) è un esempio di funzione che riceve, come argomento, un oggetto.

+ +

Una funzione può chiamare se stessa. Per esempio, ecco una funzione che calcola in modo ricorsivo i fattoriali ( molto simile alla funzione fac() vista poco prima in questa stessa pagina ):

+ +
function factorial(n){
+  if ((n == 0) || (n == 1))
+    return 1;
+  else
+    return (n * factorial(n - 1));
+}
+
+ +

A questo punto, è possibile calcolare i fattoriali dei cinque numeri seguenti:

+ +
var a, b, c, d, e;
+a = factorial(1); // a gets the value 1
+b = factorial(2); // b gets the value 2
+c = factorial(3); // c gets the value 6
+d = factorial(4); // d gets the value 24
+e = factorial(5); // e gets the value 120
+
+ +

Esistono altri metodi per chiamare una funzione. Ci sono casi in cui una funzione deve essere chiamata dinamicamente, oppure casi in cui il numero degli argomenti passati alla funzione varia, oppure casi in cui il contesto della chiamata di funzione deve essere impostato ad uno specifico oggetto, determinato in runtime ( tempo di esecuzione ). È chiaro che le funzioni sono, esse stesse, oggetti, e che questi oggetti hanno propri metodi (vedi l'oggetto Function). Uno di questi metodi, apply(), può essere usato a questo scopo.

+ +

Lo scope di una funzione

+ +

Alle variabili definite all'interno di una funzione non è possibile accedere dall'esterno della funzione, poichè la variabile è definita solo per lo scope della funzione ( scope: portata, ambiente, ambito in cui il nome della variabile può essere utilizzato per riferirsi ad essa ). Tuttavia, una funzione può accedere a tutte le variabili e a tutte le funzioni definite all'interno dello scope in cui è stata definita. In altre parole, una funzione definita nello scope globale può accedere a tutte le variabili definite nello scope globale. Una funzione definita all'interno di un'altra funzione può accedere anche a tutte le variabili definite nella funzione genitrice ( parent ), oltre che a tutte le altre variabili alle quali può accedere la funzione genitrice.

+ +
// Queste variabili sono definite nello scope globale
+
+var num1 = 20,
+    num2 = 3,
+    name = "Chamahk";
+
+// Questa funzione è definita nello scope globale
+
+function multiply() {
+    return num1 * num2;
+    }
+
+multiply(); // restituisce 60
+
+// Un esempio di funzione annidata
+function getScore () {
+  var num1 = 2,
+      num2 = 3;
+
+  function add() {
+    return name + " scored " + (num1 + num2);
+  }
+
+  return add();
+}
+
+getScore(); // restituisce "Chamahk scored 5"
+
+ +

Scope e lo stack della funzione

+ +

Ricorsione

+ +

Una funzione può chiamare se stessa. Esistono tre modi per una funzione di chiamare se stessa:

+ +
    +
  1. il nome della funzione
  2. +
  3. arguments.callee
  4. +
  5. una variabile in-scope che fa da riferimento alla funzione
  6. +
+ +

Per esempio, considerate la seguente definizione di funzione:

+ +
var foo = function bar() {
+   // statements go here
+};
+
+ +

All'interno del corpo della funzione, le tre seguenti istruzioni sono equivalenti:

+ +
    +
  1. bar()
  2. +
  3. arguments.callee()
  4. +
  5. foo()
  6. +
+ +

Una funzione che chiama se stessa viene detta funzione ricorsiva. In qualche modo, la ricorsione è analoga ad un loop. Entrambi eseguono lo stesso codice più volte ed entrambi richiedono una condizione (per evitare un loop infinito, o piuttosto, una ricorsione infinita, in questo caso). Per esempio, il loop seguente:

+ +
var x = 0;
+while (x < 10) { // "x < 10" is the loop condition
+   // do stuff
+   x++;
+}
+
+ +

può essere convertito in una funzione ricorsiva e in una chiamata a quella funzione:

+ +
function loop(x) {
+  if (x >= 10) // "x >= 10" is the exit condition (equivalent to "!(x < 10)")
+    return;
+  // do stuff
+  loop(x + 1); // the recursive call
+}
+loop(0);
+
+ +

Tuttavia, alcuni algoritmi non possono essere semplici loop iterativi. Per esempio, per avere tutti i nodi di una struttura ad albero (per esempio, il DOM) è molto più semplice usare la ricorsione:

+ +
function walkTree(node) {
+  if (node == null) //
+    return;
+  // do something with node
+  for (var i = 0; i < node.childNodes.length; i++) {
+    walkTree(node.childNodes[i]);
+  }
+}
+
+ +

Paragonato alla funzione loop, ciascuna chiamata ricorsiva, qui, esegue, a sua volta, molte chiamate ricorsive.

+ +

È possibile convertire qualsiasi algoritmo ricorsivo in un algoritmo non ricorsivo, ma spesso la logica è molto più complessa e per farlo è necessario utilizzare uno stack. In effetti, la ricorsione stessa usa uno stack: lo stack della funzione.

+ +

Un comportamento paragonabile allo stack può essere visto nell'esempio seguente:

+ +
function foo(i) {
+  if (i < 0)
+    return;
+  console.log('begin:' + i);
+  foo(i - 1);
+  console.log('end:' + i);
+}
+foo(3);
+
+// Output:
+
+// begin:3
+// begin:2
+// begin:1
+// begin:0
+// end:0
+// end:1
+// end:2
+// end:3
+ +

Funzioni annidate e chiusure

+ +

È possibile annidare una funzione all'interno di una funzione. La funzione annidata ( interna ) è privata, rispetto alla funzione che la contiene (outer o esterna). Essa forma anche una chiusura ( closure ). Una chiusura è un'espressione (normalmente, una funzione) che può avere variabili libere ( non locali ) legate ad un ambiente (ambiente che "chiude" l'espressione).

+ +

Dal momento in cui una funzione annidata è una chiusura, una funzione annidata può "ereditare" gli argomenti e le variabili della sua funzione contenitore (esterna o genitrice). In altre parole, la funzione interna contiene lo scope ( ambiente ) della funzione esterna.

+ +

Per riepilogare:

+ + + + + +

Ecco un esempio di funzione annidata:

+ +
function addSquares(a,b) {
+  function square(x) {
+    return x * x;
+  }
+  return square(a) + square(b);
+}
+a = addSquares(2,3); // restituisce 13
+b = addSquares(3,4); // restituisce 25
+c = addSquares(4,5); // restituisce 41
+
+ +

Dal momento in cui la funzione interna forma una chiusura, è possibile chiamare la funzione esterna e specificare gli argomenti per entrambe le funzioni, quella esterna e quella interna:

+ +
function outside(x) {
+  function inside(y) {
+    return x + y;
+  }
+  return inside;
+}
+fn_inside = outside(3); // Come dire: dammi una funzione che addizioni 3 a qualsiasi altro valore le venga passato
+result = fn_inside(5); // restituisce 8
+
+result1 = outside(3)(5); // restituisce 8
+
+ +

Persistenza delle variabili

+ +

Da notare come x venga preservata anche all'uscita da inside. Una chiusura deve preservare argomenti e variabili in tutti gli scope ai quali è riferita. Poichè ogni chiamata potrebbe trasportare argomenti differenti, per ogni chiamata alla funzione outside viene creata una nuova chiusura. La memoria può essere liberata solo quando inside non è più accessibile.

+ +

Una chiusura non è differente da un riferimento ad un oggetto, ma è meno ovvia di quest'ultimo, perchè non richiede di impostare direttamente il riferimento e perchè non è possibile ispezionare l'oggetto al quale il riferimento punta.

+ +

Funzioni annidate multiple

+ +

Le funzioni possono essere annidate a più livelli. Per esempio, una funzione (A), può contenere una funzione (B), che può contenere, a sua volta, una funzione (C). Entrambe le funzioni B e C formano una chiusura, qui, così B può accedere ad A e C può accedere a B. Inoltre, visto che C può accedere a B che può accedere ad A, C può anche accedere ad A. Quindi, le chiusure possono contenere più scope; ciascuna chiusura contiene lo scope delle funzioni che la contengono. Questo meccanismo è chiamato scope chaining ( catena di scope ). (Perchè è chiamata "catena" sarà chiaro tra poco.)

+ +

Considerate l'esempio seguente:

+ +
function A(x) {
+  function B(y) {
+    function C(z) {
+      console.log(x + y + z);
+    }
+    C(3);
+  }
+  B(2);
+}
+A(1); // logs 6 (1 + 2 + 3)
+
+ +

In questo esempio, C accede alla variabile y di B e alla x di A. Questo accade perchè:

+ +
    +
  1. B forma una chiusura che include A: quindi, B può accedere agli argomenti ed alle variabili di A.
  2. +
  3. C forma una chiusura che include B.
  4. +
  5. Poichè la chiusura di B include A, la chiusura di C include A; C può accedere agli argomenti ed alle variabili sia di B che di A. In altre parole, C unisce in una catena gli scope di B ed A in quell'ordine.
  6. +
+ +

Il contrario, tuttavia, non è vero. A non può accedere a C, perchè A non può accedere ad alcun argomento o variabile di B, di cui C è una variabile. Quindi, C resta privata solo a  B.

+ +

Conflitti tra nomi

+ +

Quando due argomenti o variabili, all'interno degli scope di una chiusura hanno lo stesso nome, nasce un conflitto tra nomi. Gli scope più interni hanno la precedenza, così lo scope più annidato ha la precedenza più elevata, mentre lo scope più esterno ha la precedenza più bassa. Questa è la catena degli scope. Il primo della catena è lo scope più annidato, mentre l'ultimo è lo scope più esterno. Vediamo il seguente esempio:

+ +
function outside() {
+  var x = 10;
+  function inside(x) {
+    return x;
+  }
+  return inside;
+}
+result = outside()(20); // returns 20 instead of 10
+ +

Il conflitto tra nomi avviene con l'istruzione return x ed è tra il nome del parametro x di inside ed il nome della variabile x di outside. La catena di scope qui è {inside, outside, global object}. Quindi, la x di inside ha la precedenza sulla x di outside: il valore restituito, alla fine, sarà 20 ( la x di inside ) e non 10 ( la x di  outside ).

+ +

Closure

+ +

Le closure sono uno dei meccanismi più potenti di JavaScript. JavaScript permette l'annidamento di funzioni e riconosce alla funzione interna il pieno accesso a tutte le variabili e a tutte le funzioni definite nella funzione esterna ( e a tutte le altre variabili e funzioni cui la funzione esterna ha accesso ). Tuttavia, la funzione esterna non ha accesso alle variabili ed alle funzioni definite nella funzione interna. Questo offre una certa protezione alle variabili della funzione interna. Inoltre, dal momento in cui la funzione interna ha accesso allo scope della funzione esterna, le variabili e le funzioni definite nella funzione esterna sopravviveranno alla funzione esterna stessa, se la funzione interna fa in modo di sopravvivere alla funzione esterna. Una closure viene creata quando la funzione interna viene resa disponibile in qualche modo agli scope esterni alla funzione esterna.

+ +
var pet = function(name) {   // La funzione esterna definisce una variabile di nome "name"
+  var getName = function() {
+    return name;             // La funzione interna ha accesso alla variabile "name" della funzione esterna
+  }
+  return getName;            // restituisce la funzione interna, esponendola, quindi, a scope esterni
+},
+myPet = pet("Vivie");
+
+myPet();                     // restituisce "Vivie"
+
+ +

Può essere molto più complicato del codice scritto sopra. Può essere restituito un oggetto contenente metodi per manipolare le variabili interne della funzione esterna.

+ +
var createPet = function(name) {
+  var sex;
+
+  return {
+    setName: function(newName) {
+      name = newName;
+    },
+
+    getName: function() {
+      return name;
+    },
+
+    getSex: function() {
+      return sex;
+    },
+
+    setSex: function(newSex) {
+      if(typeof newSex == "string" && (newSex.toLowerCase() == "male" || newSex.toLowerCase() == "female")) {
+        sex = newSex;
+      }
+    }
+  }
+}
+
+var pet = createPet("Vivie");
+pet.getName();                  // Vivie
+
+pet.setName("Oliver");
+pet.setSex("male");
+pet.getSex();                   // male
+pet.getName();                  // Oliver
+
+ +

Nel codice sopra, la variabile name della funzione esterna è accessibile alle funzioni interne e non c'è modo di accedere alle variabili interne, se non attraverso le funzioni interne. Le variabili interne della funzione interna agiscono come magazzino sicuro per le funzioni interne. Esse conservano i dati "persistenti" e sicuri che le funzioni interne utilizzano. Le funzioni non hanno nemmeno bisogno di vedersi assegnare ad una variabile o di avere un nome.

+ +
var getCode = (function(){
+  var secureCode = "0]Eal(eh&2";    // A code we do not want outsiders to be able to modify...
+
+  return function () {
+    return secureCode;
+  };
+})();
+
+getCode();    // Returns the secureCode
+
+ +

Ci sono, tuttavia, alcuni pericoli dai quali guardarsi, quando si utilizzano le closure. Se una funzione chiusa definisce una variabile che ha lo stesso nome di una variabile definita nello scope esterno, non sarà più possibile riferirsi alla variabile esterna.

+ +
var createPet = function(name) {  // Outer function defines a variable called "name"
+  return {
+    setName: function(name) {    // Enclosed function also defines a variable called "name"
+      name = name;               // ??? How do we access the "name" defined by the outer function ???
+    }
+  }
+}
+
+ +

È davvero  complicato usare la variabile magica this nelle closure. La variabile this è da usarsi con cautela, poichè ciò a cui this si riferisce dipende esclusivamente da dove è stata invocata la funzione, piuttosto che da dove è stata definita.

+ +

Usare l'oggetto arguments

+ +

Gli argomenti di una funzione vengono memorizzati in un oggetto, strutturato come un array. All'interno di una funzione, è possibile riferirsi agli argomenti passati alla funzione stessa nel modo seguente:

+ +
arguments[i]
+
+ +

dove i è il numero ordinale dell'argomento, a partire da zero. Così, il primo argomento passato ad una funzione sarà arguments[0]. Il numero totale degli argomenti è dato da arguments.length.

+ +

Usando l'oggetto arguments, è possibile chiamare una funzione con più argomenti di quanti ne possa formalmente accettare. Questo è spesso utile se non si sa in anticipo quanti argomenti verranno passati alla funzione. Si può usare l'attributo  arguments.length per determinare il numero degli argomenti realmente passati alla funzione, per poi accedere a ciascuno di essi usando l'oggetto arguments.

+ +

Prendiamo, per esempio, una funzione che unisca più stringhe. Il solo argomento formale previsto per la funzione è una stringa che specifica i caratteri da usare per separare le singole voci. La funzione viene definita così:

+ +
function myConcat(separator) {
+   var result = "", // initialize list
+       i;
+   // iterate through arguments
+   for (i = 1; i < arguments.length; i++) {
+      result += arguments[i] + separator;
+   }
+   return result;
+}
+
+ +

È possibile passare una quantità qualsiasi di argomenti alla funzione e la funzione comporrà una stringa testuale contenente tutti gli argomenti passati:

+ +
// returns "red, orange, blue, "
+myConcat(", ", "red", "orange", "blue");
+
+// returns "elephant; giraffe; lion; cheetah; "
+myConcat("; ", "elephant", "giraffe", "lion", "cheetah");
+
+// returns "sage. basil. oregano. pepper. parsley. "
+myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley");
+
+ +
+

Nota: La variabile arguments è simile ad un array (  "array-like" ), ma non è un array. È simile ad un array poichè ha un indice numerato ed una proprietà length. Tuttavia, non possiede tutti i metodi di manipolazione degli array.

+
+ +

Vedi l'oggetto Function nella JavaScript reference, per avere maggiori informazioni.

+ +

I parametri di una funzione

+ +

A partire da ECMAScript 6, esistono due nuovi tipi di parametri: i parametri di default e i parametri rest.

+ +

I parametri di default

+ +

In JavaScript, i parametri di una funzione hanno come valore di default undefined. Tuttavia, in alcune situazioni potrebbe essere utile impostare un diverso valore di default. In questo, possono aiutare i parametri di default.

+ +

In passato, la strategia comune per impostare i valori di default era quella di verificare i valori dei parametri, all'interno del corpo della funzione, ed assegnare loro un valore, nel caso fossero stati undefined. Se nell'esempio seguente non venisse passato, durante la chiamata, alcun valore per b, il suo valore sarebbe undefined, anche quando venisse valutata l'istruzione a*b, e la chiamata a multiply restituirebbe NaN ( Not a Number ). Tuttavia, questo valore viene definito nella seconda riga:

+ +
function multiply(a, b) {
+  b = typeof b !== 'undefined' ?  b : 1;
+
+  return a*b;
+}
+
+multiply(5); // 5
+
+ +

Con i parametri di deafult, la verifica all'interno del corpo della funzione non è più necessaria. Ora, è possibile mettere 1 come valore di default per b nella dichiarazione della funzione:

+ +
function multiply(a, b = 1) {
+  return a*b;
+}
+
+multiply(5); // 5
+ +

Per maggiori dettagli, vedi paremetri di default nella Javascript reference.

+ +

I parametri Rest

+ +

La sintassi dei rest parameter permette di rappresentare un indefinito numero di argomenti come un array. Nell'esempio, usiamo i parametri rest per rappresentare l'insieme degli argomenti composto dagli argomenti successivi al primo ( a partire dal secondo argomento fino alla fine ). Poi, moltiplichiamo ciascun argomento dell'insieme per il primo. Questo esempio utilizza una funzione a freccia, che verrà introdotta nella prossima sezione.

+ +
function multiply(multiplier, ...theArgs) {
+  return theArgs.map(x => multiplier * x);
+}
+
+var arr = multiply(2, 1, 2, 3);
+console.log(arr); // [2, 4, 6]
+ +

Le funzioni a freccia

+ +

Una espressione di funzione a freccia ( nota anche come fat arrow function ) ha una sintassi più stringata rispetto alle espressioni di funzione e forza, lessicalmente, il valore di this. Le funzioni a freccia sono sempre anonime. Vedi anche il post di hacks.mozilla.org: "ES6 In Depth: Arrow functions".

+ +

Sono due i fattori che influenzarono l'introduzione delle funzioni a freccia: la brevità delle funzioni ed il this lessicale.

+ +

Funzioni più brevi

+ +

In alcuni modelli funzionali, funzioni più brevi sono le benvenute. Paragoniamo le due istruzioni seguenti:

+ +
var a = [
+  "Hydrogen",
+  "Helium",
+  "Lithium",
+  "Beryl­lium"
+];
+
+var a2 = a.map(function(s){ return s.length });
+var a3 = a.map( s => s.length );
+ +

Il this lessicale

+ +

Until arrow functions, every new function defined its own this value (a new object in case of a constructor, undefined in strict mode function calls, the context object if the function is called as an "object method", etc.). This proved to be annoying with an object-oriented style of programming.

+ +
function Person() {
+  // The Person() constructor defines `this` as itself.
+  this.age = 0;
+
+  setInterval(function growUp() {
+    // In nonstrict mode, the growUp() function defines `this`
+    // as the global object, which is different from the `this`
+    // defined by the Person() constructor.
+    this.age++;
+  }, 1000);
+}
+
+var p = new Person();
+ +

In ECMAScript 3/5, this issue was fixed by assigning the value in this to a variable that could be closed over.

+ +
function Person() {
+  var self = this; // Some choose `that` instead of `self`.
+                   // Choose one and be consistent.
+  self.age = 0;
+
+  setInterval(function growUp() {
+    // The callback refers to the `self` variable of which
+    // the value is the expected object.
+    self.age++;
+  }, 1000);
+}
+ +

Alternatively, a bound function could be created so that the proper this value would be passed to the growUp() function.

+ +

Arrow functions capture the this value of the enclosing context, so the following code works as expected.

+ +
function Person(){
+  this.age = 0;
+
+  setInterval(() => {
+    this.age++; // |this| properly refers to the person object
+  }, 1000);
+}
+
+var p = new Person();
+ +

Predefined functions

+ +

JavaScript has several top-level, built-in functions:

+ +
+
{{jsxref("Global_Objects/eval", "eval()")}}
+
+

The eval() method evaluates JavaScript code represented as a string.

+
+
{{jsxref("Global_Objects/uneval", "uneval()")}} {{non-standard_inline}}
+
+

The uneval() method creates a string representation of the source code of an {{jsxref("Object")}}.

+
+
{{jsxref("Global_Objects/isFinite", "isFinite()")}}
+
+

The global isFinite() function determines whether the passed value is a finite number. If needed, the parameter is first converted to a number.

+
+
{{jsxref("Global_Objects/isNaN", "isNaN()")}}
+
+

The isNaN() function determines whether a value is {{jsxref("Global_Objects/NaN", "NaN")}} or not. Note: coercion inside the isNaN function has interesting rules; you may alternatively want to use {{jsxref("Number.isNaN()")}}, as defined in ECMAScript 6, or you can use typeof to determine if the value is Not-A-Number.

+
+
{{jsxref("Global_Objects/parseFloat", "parseFloat()")}}
+
+

The parseFloat() function parses a string argument and returns a floating point number.

+
+
{{jsxref("Global_Objects/parseInt", "parseInt()")}}
+
+

The parseInt() function parses a string argument and returns an integer of the specified radix (the base in mathematical numeral systems).

+
+
{{jsxref("Global_Objects/decodeURI", "decodeURI()")}}
+
+

The decodeURI() function decodes a Uniform Resource Identifier (URI) previously created by {{jsxref("Global_Objects/encodeURI", "encodeURI")}} or by a similar routine.

+
+
{{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent()")}}
+
+

The decodeURIComponent() method decodes a Uniform Resource Identifier (URI) component previously created by {{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}} or by a similar routine.

+
+
{{jsxref("Global_Objects/encodeURI", "encodeURI()")}}
+
+

The encodeURI() method encodes a Uniform Resource Identifier (URI) by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character (will only be four escape sequences for characters composed of two "surrogate" characters).

+
+
{{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent()")}}
+
+

The encodeURIComponent() method encodes a Uniform Resource Identifier (URI) component by replacing each instance of certain characters by one, two, three, or four escape sequences representing the UTF-8 encoding of the character (will only be four escape sequences for characters composed of two "surrogate" characters).

+
+
{{jsxref("Global_Objects/escape", "escape()")}} {{deprecated_inline}}
+
+

The deprecated escape() method computes a new string in which certain characters have been replaced by a hexadecimal escape sequence. Use {{jsxref("Global_Objects/encodeURI", "encodeURI")}} or {{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}} instead.

+
+
{{jsxref("Global_Objects/unescape", "unescape()")}} {{deprecated_inline}}
+
+

The deprecated unescape() method computes a new string in which hexadecimal escape sequences are replaced with the character that it represents. The escape sequences might be introduced by a function like {{jsxref("Global_Objects/escape", "escape")}}. Because unescape() is deprecated, use {{jsxref("Global_Objects/decodeURI", "decodeURI()")}} or {{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent")}} instead.

+
+
+ +

{{PreviousNext("Web/JavaScript/Guide/Loops_and_iteration", "Web/JavaScript/Guide/Expressions_and_Operators")}}

diff --git a/files/it/web/javascript/guide/grammar_and_types/index.html b/files/it/web/javascript/guide/grammar_and_types/index.html new file mode 100644 index 0000000000..2a43d5230d --- /dev/null +++ b/files/it/web/javascript/guide/grammar_and_types/index.html @@ -0,0 +1,659 @@ +--- +title: Grammatica e tipi +slug: Web/JavaScript/Guida/Grammar_and_types +translation_of: Web/JavaScript/Guide/Grammar_and_types +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Introduction", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}
+ +

Questo capitolo tratta la sintassi di base di JavaScript, le dichiarazioni di variabili, i tipi di dati e i letterali.

+ +

Nozioni di base

+ +

JavaScript mutua molta della sua sintassi da Java, ma è anche influenzato da Awk, Perl e Python.

+ +

JavaScript è sensibile al maiuscolo-minuscolo (case-sensitive) e usa l'insieme di caratteri Unicode.

+ +

In JavaScript, le istruzioni sono separate da punto e vigola (;). Spazi, tabulazioni e caratteri di a capo sono chiamati spazi bianchi. Il testo sorgente di uno script JavaScript viene analizzato da sinistra verso destra ed è convertito in una sequenza di elementi di input che sono: token, caratteri di controllo, terminatori di linea, commenti o spazi bianchi. ECMAScript definisce anche determinate parole chiave e letterali e ha delle regole per l'inserimento automatico dei punti e virgola (ASI) per chiudere le istruzioni. Tuttavia si raccomanda di aggiungere sempre un punto e virgola per terminare ogni istruzione, questo eviterà effetti collaterali. Per maggiori informazioni si veda il riferimento dettagliato riguardo la lexical grammar di JavaScript.

+ +

Commenti

+ +

La sintassi dei commenti è la stessa di quelli del C++ e di molti altri linguaggi:

+ +
// una linea di commento
+
+/* questo è un commento più lungo,
+   occupa più linee
+ */
+
+/* Però non puoi /* annidare i commenti */ SyntaxError */
+ +

Dichiarazioni

+ +

Ci sono tre tipi di dichiarazioni in JavaScript.

+ +
+
{{jsxref("Statements/var", "var")}}
+
Dichiarazione di una variabile, opzionalmente inizializzata ad un valore.
+
{{experimental_inline}} {{jsxref("Statements/let", "let")}}
+
Dichiarazione di una variabile locale con visibilità nel blocco, opzionalmente inizializzata ad un valore.
+
{{experimental_inline}} {{jsxref("Statements/const", "const")}}
+
Dichiarazione di una costante in sola lettura con un nome.
+
+ +

Variabili

+ +

Le variabili sono nomi simbolici da usare nelle applicazioni in luogo dei valori che rappresentano. I nomi delle variabili, chiamati  {{Glossary("Identifier", "identificatori")}}, devono seguire certe regole di scrittura.

+ +

Un identificatore JavaScript deve iniziare con una lettera, un trattino basso (_) o segno del dollaro ($), mentre i caratteri successivi possono anche essere le cifre (0-9). Siccome JavaScript è case-sensitive, le lettere includono i caratteri da "A" fino a "Z" (maiuscoli) e i caratteri da "a" fino a "z" (minuscoli).

+ +

Si possono usare anche le lettere ISO 8859-1 o Unicode come per esempio å e ü negli identificatori. Possono essere usate anche le sequenze di escape di Unicode come caratteri negli identificatori.

+ +

Alcuni esempi di nomi leciti sono Number_hits, temp99 e _name.

+ +

Dichiarazione di variabili

+ +

Una variabile può essere dichiarata in tre modi:

+ + + +

Valutazione delle variabili

+ +

Una variabile dichiarata usando le istruzioni  var o let senza nessun valore iniziale specificato ha il valore {{jsxref("undefined")}}.

+ +

Il tentativo di accedere ad una variabile non dichiarata o di accedere ad un identificatore dichiarato con l'istruzione let, prima di una sua inizializzazione, provocherà un'eccezione di {{jsxref("ReferenceError")}}:

+ +
var a;
+console.log("Il valore di a è " + a); // Scrive nel log "Il valore di a è undefined"
+
+console.log("Il valore di b è " + b); // Solleva una eccezione ReferenceError
+
+console.log("Il valore di c è " + c); // Scrive nel log "Il valore di c è undefined" 
+var c;
+
+console.log("Il valore di x è " + x); // Solleva una eccezione ReferenceError: x is not defined
+let x;
+ +

Si può usare undefined per determinare se una variabile ha un valore oppure no. Nel codice seguente alla variabile input non è stato assegnato un valore e la condizione dell'istruzione if è

+ +

valuta a true.

+ +
var input;
+if(input === undefined){
+  faiQuesto();
+} else {
+  faiQuello();
+}
+
+ +

Il valore undefined si comporta come false quando viene usato in un contesto booleano. Ad esempio il codice seguente esegue la funzione miaFunzione perché l'elemento di mioArray non è definito:

+ +
var mioArray = [];
+if (!mioArray[0]) miaFunzione();
+
+ +

Il valore undefined viene convertito in NaN quando viene usato in un contesto numerico.

+ +
var a;
+a + 2;  // Viene valutato a NaN
+ +

Quando viene valutata una variabile {{jsxref("null")}}, il valore null si comporta come 0 in un contesto numerico e false in un contesto booleano. Per esempio:

+ +
var n = null;
+console.log(n * 32); // Visualizzera nella console 0
+
+ +

Visibilità delle variabili

+ +

Quando una variabile viene dichiarata fuori da una qualsiasi funzione viene chiamata variabile globale, poiché è disponibile  in tutto il codice nel documento corrente. Quando invece la variabile viene dichiarata in una funzione viene chiamata variabile locale, perché è disponibile soltanto all'interno di quella funzione.

+ +

JavaScript prima di ECMAScript 2015 non aveva una visibilità a livello di blocco; piuttosto una variabile dichiarata all'interno di un blocco era locale alla funzione (o al contesto globale) in cui il blocco risiedeva. Per esempio il seguente codice scriverà nel log 5, perché la visibilità di x è la funzione (o il contesto globale) all'interno del quale x viene dichiarata e non il blocco, che in questo caso è l'istruzione if.

+ +
if (true) {
+  var x = 5;
+}
+console.log(x);  // 5
+
+ +

Il comportamento cambia quando si usa l'istruzione let introdotta in ECMAScript 2015.

+ +
if (true) {
+  let y = 5;
+}
+console.log(y);  // ReferenceError: y non è definita
+
+ +

Sollevamento delle variabili

+ +

Un'altra cosa inusuale riguardo le variabili in JavaScript è che si può fare riferimento ad una variabile dichiarata più avanti nello script senza causare una eccezione. Questo concetto è conosciuto come innalzamento (hoisting); le variabili in JavaScript sono in un certo senso "sollevate" o spostate all'inizio della definizione del corpo della funzione o dell'istruzione. Tuttavia le variabili che sono state sollevate ritornano il valore undefined. Dunque se viene usata (o si fa riferimento ad) una variabile prima che venga dichiarata questa ritornà undefined.

+ +
/**
+ * Esempio 1
+ */
+console.log(x === undefined); // visualizza "true" nel log
+var x = 3;
+
+/**
+ * Esempio 2
+ */
+var myvar = "mio valore";
+
+(function() {
+  console.log(myvar); // visualizza "undefined" nel log
+  var myvar = "valore locale";
+})();
+
+ +

L'esempio sopra sarà interpretato nello stesso modo di:

+ +
/**
+ * Esempio 1
+ */
+var x;
+console.log(x === undefined); // visualizza nel log "true"
+x = 3;
+
+/**
+ * Esempio 2
+ */
+var myvar = "mio valore";
+
+(function() {
+  var myvar;
+  console.log(myvar); // undefined
+  myvar = "valore locale";
+})();
+
+ +

Per via dell'innalzamento, tutte le istruzioni var in una funzione dovrebbero essere posizionate prima di ogni altra istruzione che vada a definire una funzione. Questa buona pratica incrementa la chiarezza del codice.

+ +

In ECMAScript 2015, let (const) non solleverà/sposterà la variabile all'inizio della dichiarazione del blocco, dunque un riferimento alla variabile nel blocco prima che questa venga dichiarata risulterà in un'eccezione di {{jsxref("ReferenceError")}}. La variabile si dice in una "zona temporale morta" ("temporal dead zone") dall'inizio del blocco fino alla a che non si incontri la sua dichiarazione.

+ +
console.log(x); // Solleverà un'eccezione ReferenceError
+let x = 3
+ +

Sollevamento delle Funzioni

+ +

Nel caso delle funzioni, solo la dichiarazione della funzione verrà spostata all'inizio. Se la funzione viene introdotta da un'espressione, in questo caso non verrà spostata.

+ +
/* Function declaration */
+
+foo(); // "bar"
+
+function foo() {
+  console.log("bar");
+}
+
+
+/* Function expression */
+
+baz(); // TypeError: baz is not a function
+
+var baz = function() {
+  console.log("bar2");
+};
+ +

Variabli globali

+ +

Le variabili globali sono in effetti proprietà dell'oggetto globale. Nelle pagine web l'oggetto globale è {{domxref("window")}} quindi è possibile impostare e accedere alle variabili globali usando la sintassi window.variabile.

+ +

Di conseguenza è possibile accedere a variabili globali dichiarate in una finestra o un frame da un'altra finestra o frame specificando il nome della finestra o del frame. Per esempio, se una variabile chiamata numeroDiTelefono è dichiarata in un documento, è possibile far riferimento a questa variabile dall'interno di un iframe come parent.numeroDiTelefono.

+ +

Costanti

+ +

È possibile creare una costante in sola lettura dandole un nome usando la parola chiave {{jsxref("Statements/const", "const")}}. La sintassi di un identificatore di costante è la stessa di un identificatore di variabile: deve iniziare con una lettera, trattino basso (_) o segno del dollaro ($) e può contenere caratteri alfabetici, numerici o trattini bassi.

+ +
const PI = 3.14;
+
+ +

Una costante non può cambiare il suo valore attraverso ulteriori assegnazioni o essere ridichiarata mentre lo script è in esecuzione. Deve anche essere inizializzata ad un valore.

+ +

Le regole di visibilità per le costanti sono le stesse di quelle per le variabil con visibilità al livello di blocco dichiarate con l'istruzione let. Se la parola chiave const viene omessa si assume che l'identificatore rappresenta una variabile.

+ +

Non è possibile dichiarare una costante con lo stesso nome di una funzione o di una variabile nello stesso spazio di visibilità. Per esempio:

+ +
// QUESTO CAUSERÀ UN ERRORE
+function f() {};
+const f = 5;
+
+// ANCHE QUESTO CAUSERÀ UN ERRORE
+function f() {
+  const g = 5;
+  var g;
+
+  //istruzioni
+}
+
+ +

Strutture dati e tipi

+ +

Tipi di dato

+ +

L'ultimo standard ECMAScript definisce sette tipi di dati:

+ + + +

Sebbene questi tipi di dati siano relativamente pochi questi permettono di eseguire funzioni utili nelle applicazioni. {{jsxref("Object", "Objects")}} e {{jsxref("Function", "functions")}} sono altri elementi fondamentali nel linguaggio. Si può pensatre agli oggetti come a contenitori con un nome per dei valori e alle funzioni come a procedure che l'applicazione può compiere.

+ +

Conversione dei tipi dei dati

+ +

JavaScript è un linguaggio con tipi assegnati dinamicamente. Questo significa che non si va a specificare il tipo di dato che una variabile conterrà quando viene dichiarata e anche che il tipo di un dato viene convertito automaticamente a seconda delle necessità durante l'esecuzione dello script. Così, per esempio, si può definire una variabile come segue:

+ +
var risposta = 42;
+
+ +

E più avanti è possibile assegnare alla stessa variabile un valore testo (stringa), per esempio:

+ +
risposta = "Grazie per tutti i pesci...";
+
+ +

Poiché in JavaScript i tipi si assegnano dinamicamente questa assegnazione non causerà un messaggio di errore.

+ +

Nelle espressioni che coinvolgono valori numerici e stringhe con l'operatore + JavaScript converte i valori numerici in stringhe. Per esempio si considerino le seguenti istruzioni:

+ +
x = "La risposta è " + 42 // "La risposta è 42"
+y = 42 + " è la risposta" // "42 è la risposta"
+
+ +

In istruzioni che coinvolgono altri operatori JavaScript non converte valori numerici in stringa. Per esempio:

+ +
"37" - 7 // 30
+"37" + 7 // "377"
+
+ +

Conversione delle stringhe in numeri

+ +

Nel caso in cui il valore che rappresenta un numero è memorizzato come stringa ci sono dei metodi per eseguire la conversione:

+ + + +

parseInt ritornerà soltanto numeri interi,  ha una utilità ridotta per i numeri decimali. In aggiunta è buona pratica nell'uso di parseInt includere il parametro base, questo parametro è usato per specificare quale sistema di numerazione deve essere usato.

+ +

Un metodo alternativo per recuperare un numero da un testo è di usare l'operatore + (più unario):

+ +
"1.1" + "1.1" = "1.11.1"
+(+"1.1") + (+"1.1") = 2.2
+// Note: le parentesi sono aggiunte per chiarezza, non sono richieste.
+ +

Letterali

+ +

I letterali sono usati per rappresentare i valori in JavaScript. Questi sono valori fissati, non variabili, che venvono letteralmente inseriti nello script. Questa sezione descrive i seguenti tipi di letterali:

+ + + +

Letterali di array

+ +

Un letterale di array è un elenco di zero o più espressioni ognuna delle quali rappresenta un elemento dell'array, inclusa in parentesi quadre ([]). Quando si crea un array usando un letterale l'array stesso viene inizializzato con i valori specificati come elementi, la sua lunghezza è impostata al numero di elementi specificati.

+ +

Il seguente esempio crea un array tipiDiCaffe con tre elementi e una lunghezza di tre:

+ +
var tipiDiCaffe = ["French Roast", "Colombian", "Kona"];
+
+ +
+

Nota: Un letterale di array è un tipo di inizializzatore di oggetto. Vedi Usando inizializzatori di Oggetti.

+
+ +

Se un array viene creato usando un letterale in uno script top-level, JavaScript interpreta l'array ogni volta che valuta l'espressione che contiene l'array letterale. In aggiunta l'array letterale usato in una funzione viene creato ogni volta che la funzione viene chiamata.

+ +

Gli array letterali sono anche oggetti Array. Si veda {{jsxref("Array")}} e Collezione indicizzata per i dettagli sugli oggetti Array.

+ +

Virgole aggiuntive negli array letterali

+ +

Non è obbligatorio specificare tutti gli elementi in un array letterale. Mettendo due virgole in fila l'array viene creato con il valore undefined per gli elementi non specificati. Il seguente esempio crea l'array pesce:

+ +
var pesce = ["Leone", , "Angelo"];
+
+ +

Questo array ha due elementi con un valore e un elemento vuoto (pesce[0] is "Leone", pesce[1] è undefined, e pesce[2] è "Angelo").

+ +

Inserendo una virgola in fondo alla lista degli elementi la virgola stessa verrà ignorata. Nel seguente esempio la lunghezza dell'array è tre, non c'è un miaLista[3]. Tutte le altre virgole nell'elenco indicano un elemento nuovo.

+ +
+

Nota: Le virgole in coda possono creare errori nelle versioni più vecchie dei browser ed è buona pratica rimuoverle.

+
+ +
var miaLista = ['casa', , 'scuola', ];
+
+ +

Nel seguente esempio la lunghezza dell'array è quattro e miaLista[0] e mialista[2] sono mancanti.

+ +
var miaLista = [ , 'casa', , 'scuola'];
+
+ +

Nel seguente esempio la lunghezza dell'array è quattro e mialista[1] e miaLista[3] sono mancanti. Soltanto l'ultima virgola viene ignorata.

+ +
var miaLista = ['casa', , 'scuola', , ];
+
+ +

Comprendere il comportamento delle virgole in più è importante per comprendere JavaScript come linguaggio, in ogni caso nella scrittura del codice: è buona norma dichiarare esplicitamente gli elementi mancanti come undefined, questo migliorerà la chiarezza e la manutenibilità del codice.

+ +

Letterali di booleani

+ +

Il tipo Boolean ha due valori letterali: true e false.

+ +

Non vanno confusi i valori primitivi Booleani true e false con i valori true e false dell'oggetto Boolean. L'oggetto Boolean è un involucro intorno al tipo primitivo Booleano. Vedi {{jsxref("Global_Objects/Boolean", "Boolean")}} per maggiori informazioni.

+ +

Letterali di numeri Interi

+ +

Gli interi possono essere rappresentati in decimale (base 10), esadecimale (base 16), ottale (base 8) e binario (base 2).

+ + + +

Alcuni esempi i di letterali di interi sono:

+ +
0, 117 and -345 (decimale, base 10)
+015, 0001 and -0o77 (ottale, base 8)
+0x1123, 0x00111 and -0xF1A7 (esadecimale, "hex" o base 16)
+0b11, 0b0011 and -0b11 (binario, base 2)
+
+ +

Per maggiori informazioni, vedi Numeric literals in the Lexical grammar reference.

+ +

Letterali di numeri in virgola-mobile

+ +

Un letterale per un numero in virgola mobile può avere le seguenti parti:

+ + + +

La parte esponente è una "e" o "E" seguita da un intero che può essere con segno (preceduto da "+" o "-"). Un numero in virgola mobile deve avere almeno una cifra e un punto oppure una "e" (o "E").

+ +

Più concisamente la sintassi è:

+ +
[(+|-)][cifre][.cifre][(E|e)[(+|-)]cifre]
+
+ +

Per esempio:

+ +
3.1415926
+-.123456789
+-3.1E+12
+.1e-23
+
+ +

Letterali di oggetti

+ +

Un letterale di un oggetto è una lista di zero o più coppie di nomi di proprietà e valori associati di un oggetto racchiusi in parentesi graffe ({}). Non andrebbe usato un letterale di un oggetto all'inizio di una istruzione, questo porterà ad un errore o non si comporterà come ci si aspetta perché { sarà interpretata come l'inizio di un blocco.

+ +

Quello seguente è un esempio di un letterale di un oggetto. Il primo elemento dell'oggetto automobile definisce un proprietà, miaAutomobile, e gli assegna il testo "Saturn"; il secondo elemento, la proprietà getAutomobile, è immediatamente assegnata al valore risultante dall'invocazione della funzione (tipiDiAutomobile("Honda")); il terzo elemento, la proprietà speciale, usa una variabile esistente (saldi).

+ +
var saldi = "Toyota";
+
+function tipiDiAutomobile(nome) {
+  if (nome === "Honda") {
+    return nome;
+  } else {
+    return "Spiacente, noi non vendiamo " + nome + ".";
+  }
+}
+
+var automobile = { miaAutomobile: "Saturn", getAutomobile: tipiDiAutomobile("Honda"), speciale: saldi };
+
+console.log(automobile.miaAutomobile);   // Saturn
+console.log(automobile.getAutomobile);  // Honda
+console.log(automobile.speciale); // Toyota
+
+ +

In aggiunta si possono usare letterali di tipo numerico o testo come nome di una proprietà o annidare un oggetto dentro un altro. Il seguente esempio usa queste opzioni.

+ +
var automobile = { molteAutomobili: {a: "Saab", "b": "Jeep"}, 7: "Mazda" };
+
+console.log(automobile.molteAutomobili.b); // Jeep
+console.log(automobile[7]); // Mazda
+
+ +

I nomi delle proprietà degli oggetti possono essere un testo qualsiasi, incluso il testo vuoto. Se il nome della proprietà non è un {{Glossary("Identifier","identifier")}} JavaScript valido o un numero dovrà essere racchiuso tra virgolette. I nomi di proprietà che non sono identificatori validi non possono neanche essere acceduti usando il punto (.), potranno però essere acceduti e impostati usando la notazione analoga a quella degli array ("[]").

+ +
var nomiDiProprietaInusuali = {
+  "": "Una stringa vuota",
+  "!": "Bang!"
+}
+console.log(nomiDiProprietaInusuali."");   // SyntaxError: Unexpected string
+console.log(nomiDiProprietaInusuali[""]);  // Una stringa vuota
+console.log(nomiDiProprietaInusuali.!);    // SyntaxError: Unexpected token !
+console.log(nomiDiProprietaInusuali["!"]); // Bang!
+ +

In ES2015, i letterali di oggetti sono estesi per supportare l'impostazione del prototipo al momento della costruzione, forme abbreviate per le assegnazioni tipo foo: foo, definizioni di metodi, eseguire chiamate a super e calcolare il nome di proprietà con espressioni. Nel'insieme queste aggiunte avvicinano i letterali di oggetti e le dichiarazioni delle classi permettendo quindi di beneficiare di alcune delle stesse comodità della progettazione orientata agli oggetti.

+ +
var obj = {
+    // __proto__
+    __proto__: theProtoObj,
+    // Abbreviazione per ‘handler: handler’
+    handler,
+    // Metodi
+    toString() {
+     // Super calls
+     return "d " + super.toString();
+    },
+    // Nomi di proprietà calcolati (dinamici)
+    [ 'prop_' + (() => 42)() ]: 42
+};
+ +

Nota che:

+ +
var foo = {a: "alpha", 2: "two"};
+console.log(foo.a);    // alpha
+console.log(foo[2]);   // two
+//console.log(foo.2);  // Error: missing ) after argument list
+//console.log(foo[a]); // Error: a is not defined
+console.log(foo["a"]); // alpha
+console.log(foo["2"]); // two
+
+ +

Letterali di RegExp

+ +

Un letterale di espressione regolare (RegExp) è un modello (pattern) racchiuso tra barre. il seguente è un esempio di un letterale di una espressione regolare.

+ +
var re = /ab+c/;
+ +

Letterali di stringhe

+ +

Un letterale di testo (stringa nel preguo del testo) è formato da zero o più caratteri racchiusi tra virgolette doppie  (") o singole (').  Una stringa deve essere delimitata da virgolette dello stesso tipo; cioè o entrambe singole o entrambe doppie. I seguenti sono esempi di leterali di testo:

+ +
"foo"
+'bar'
+"1234"
+"una linea \n altra linea"
+"prima dell'una"
+
+ +

È possibile chiamare qualsiasi metodo dell'oggetto String su una stringa —JavaScript converte automaticamente la stringa in un oggetto temporaneo di tipo String, chiama il metodo, poi elimina l'oggetto temporaneo. È anche possibile usare la proprietà String.length con una stringa letterale:

+ +
console.log("John's cat".length)
+// Stamperà il numero di simboli nel testo inclusi gli spazi.
+// In questo caso 10.
+
+ +

In ES2015 sono disponibili i letterali modello. I letterali modello sono racchiusi tra accenti gravi (` `)  (accento grave) anziché apici doppi o singoli. Le stringhe modello fornisco dello "zucchero sintattico" per la costruzione delle stringhe. È simile all'interpolazione delle stringhe di Perl, Python e altri. Opzionalmente, un'etichetta può essere aggiunta per permettere la personalizzazione nella costruzione della stringa, evitare gli attacchi per injection o costruire strutture dati di livello più alto dal contenuto di una stringa.

+ +
// Creazione di un letterale string di base
+`In JavaScript '\n' is a line-feed.`
+
+// Stringa multilinea
+`In JavaScript this is
+ not legal.`
+
+// Interpolazione di stringhe
+var name = "Bob", time = "today";
+`Hello ${name}, how are you ${time}?`
+
+// La costruzione di un prefisso di richiesta HTTP è usata per interpretare le sostituzioni e le costruzioni
+POST`http://foo.org/bar?a=${a}&b=${b}
+     Content-Type: application/json
+     X-Credentials: ${credentials}
+     { "foo": ${foo},
+       "bar": ${bar}}`(myOnReadyStateChangeHandler);
+ +

Si dovrebbero usare i letterali stringa a meno che non ci sia specifico bisogno di usare un oggetto String. Si veda {{jsxref("String")}} per dettagli sull'oggetto String.

+ +

Uso di caratteri speciali nelle stringhe

+ +

Oltre ai caratteri ordinari si possono includere anche dei caratteri speciali nelle stringhe come mostrato nel seguente esempio.

+ +
"prima linea \n seconda linea"
+
+ +

La seguente tabella elenca i caratteri speciali che possono essere usati nelle stringhe JavaScript.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table: JavaScript caratteri speciali
CarattereSignificato
\0Byte null
\bBackspace
\fForm feed
\nNew line
\rCarriage return
\tTab
\vTab verticale
\'Apostrofo o virgoletta singola
\"Virgoletta doppia
\\Il carattere backslash
\XXXIl carattere con la codifica Latin-1 specificata da fino a tre caratteri XXX tra 0 e 377. Per esempio \251 è la sequenza ottale per il simbolo di copyright.
\xXXIl carattere con la codifica Latin-1 specificata da due cifre esadecimali XX comprese tra 00 e FF. Per esempio \xA9 è la sequenza ottale per il simbolo di copyright.
\uXXXXIl carattere Unicode specificato da quattro cifre esadecimali XXXX. Per esempio \u00A9 è la sequenza Unicode per il simbolo di copyright. Vedi Unicode escape sequences.
\u{XXXXX}Escape per Unicode code point. Per esempio \u{2F804} è la stessa cosa dell'esape semplice Unicode \uD87E\uDC04.
+ +

Caratteri a cui aggiungere il backslash (Escaping)

+ +

Per i caratteri non elencati nella tabella un backslash (\) prefisso viene ignorato, questo uso è deprecato e devrebbe essere evitato.

+ +

Le virgolette possono essere inserite in una stringa precedendole da un backslash. Questo è noto come escaping delle virgolette. Per esempio:

+ +
var quote = "Lui legge \"The Cremation of Sam McGee\" by R.W. Service.";
+console.log(quote);
+
+ +

Il risultato sarebbe:

+ +
Lui legge "The Cremation of Sam McGee" by R.W. Service.
+
+ +

Per includere un backslash in una stringa va fatto l'esape del carattere backslash. Per esempio, per assegnare il percorso c:\temp ad una stringa, usare il seguente:

+ +
var home = "c:\\temp";
+
+ +

Si può anche fare l'escape delle interruzioni di linea precedendole con un backslash. Sia il backslash che l'interruzione di linea saranno rimosse dal valore della stringa.

+ +
var str = "questa stringa \
+è spezzata \
+attraverso multiple\
+linee."
+console.log(str);   // questa stringa è spezzata attraverso multiple linee.
+
+ +

Sebbene JavaScript non abbia una sintassi tipo "heredoc", è possibile fare qualcosa di simile aggiungendo una sequenza di escape per "a capo" e facendo l'escape dell'a capo alla fine della linea:

+ +
var poem =
+"Roses are red,\n\
+Violets are blue.\n\
+I'm schizophrenic,\n\
+And so am I."
+
+ +

Ulteriori informazioni

+ +

Questo capitolo si concentra sulla sintassi di base per i tipi e le dichiarazioni. Per imparare di più riguardo i costrutti del linguaggio JavaScript vedi anche i seguenti capitoli in questa guida:

+ + + +

Nel prossimo capitolo, tratteremo i costrutti del controllo del flusso e la gestione degli errori.

+ +

{{PreviousNext("Web/JavaScript/Guide/Introduction", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}

diff --git a/files/it/web/javascript/guide/index.html b/files/it/web/javascript/guide/index.html new file mode 100644 index 0000000000..ba956f21f2 --- /dev/null +++ b/files/it/web/javascript/guide/index.html @@ -0,0 +1,124 @@ +--- +title: JavaScript Guide +slug: Web/JavaScript/Guida +tags: + - AJAX + - JavaScript + - JavaScript_Guide + - NeedsTranslation + - TopicStub +translation_of: Web/JavaScript/Guide +--- +
{{jsSidebar("JavaScript Guide")}}
+ +

La Guida JavaScript mostra come utilizzare JavaScript e offre una panoramica del linguaggio. Se hai bisogno di informazioni esaustive su una sua funzione, dai un'occhiata alle reference JavaScript.

+ +

Capitoli

+ +

Questa guida è divisa in vari capitoli:

+ + + + + + + + + +

{{Next("Web/JavaScript/Guide/Introduction")}}

diff --git a/files/it/web/javascript/guide/introduction/index.html b/files/it/web/javascript/guide/introduction/index.html new file mode 100644 index 0000000000..3825ded91c --- /dev/null +++ b/files/it/web/javascript/guide/introduction/index.html @@ -0,0 +1,140 @@ +--- +title: Introduzione +slug: Web/JavaScript/Guida/Introduzione +tags: + - Guida + - JavaScript +translation_of: Web/JavaScript/Guide/Introduction +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammar_and_types")}}
+ +

Questo capitolo introduce JavaScript e discute alcuni dei suoi concetti fondamentali.

+ +

Che cosa dovresti già sapere

+ +

Questa guida parte dal presupposto che tu abbia già queste nozioni di base:

+ + + +

Dove trovare informazioni su JavaScript

+ +

La documentazione JavaScript su MDN comprende:

+ + + +

Se sei nuovo di JavaScript, inizia con gli articoli presenti in Capire il web e nella  Guida JavaScript. Quando avrai una chiara comprensione dei fondamentali, potrai usare il  Riferimento JavaScript per apprendere maggiori dettagli su singoli oggetti e parti del linguaggio.

+ +

Che cos'è JavaScript?

+ +

JavaScript è un linguaggio di scripting cross-platform e object-oriented. È un linguaggio piccolo e leggero. All interno di un ambiente ospite (ad esempio un web browser), JavaScript può essere connesso agli oggetti del suo ambiente per fornire controllo programmatico su di essi.

+ +

JavaScript contiene una libreria standard di oggetti come Array, Date e Math, ed una serie di elementi base del linguaggio come operatori, strutture di controllo e dichiarazioni. La base di JavaScript può essere estesa per una varietà di scopi fornendogli oggetti aggiuntivi; ad esempio:

+ + + +

JavaScript e Java

+ +

JavaScript e Java sono simili per certi aspetti, ma fondamentalmente diversi per altri. Il linguaggio JavaScript assomiglia a Java ma non ha la tipizzazione statica ed il controllo forte dei tipi di Java. JavaScript segue larga parte della sintassi delle espressioni di Java, la convenzione sui nomi ed i principali costrutti di controllo di flusso, e questa è la ragione per cui è stato rinominato da LiveScript a JavaScript.
+ A differenza del sistema di classi costruito dalle dichiarazione a tempo di compilazione di Java, JavaScript supporta un sistema runtime basato su un piccolo numero di tipi di dato che rappresentano valori Booleani, numerici e di tipo stringa. JavaScript dispone di un modello ad oggetti basato su prototype al posto del più comune modello ad oggetti basato su classi. Il modello prototype-based fornisce ereditarietà dinamica; che significa che ciò che viene ereditato può variare per singoli oggetti. JavaScript inoltre supporta funzioni senza speciali requisiti dichiarativi. Le funzioni possono essere proprietà di oggetti, eseguite come metodi debolmente tipizzati.

+ +

JavaScript è un linguaggio con un formalismo molto libero se confrontato a Java. Non è necessario dichiarare tutte le variabili, classi e metodi. Non ci si deve preoccupare se i metodi sono public, privare e protected, e non è necessario implementare interfacce. Variabili, parametri e valori di ritorno delle funzioni non sono tipizzati in modo esplicito.

+ +

Java è un linguaggio di programmazione basato su classi progettato per essere veloce e con un controllo dei tipi rigoroso. Con controllo dei tipi rigoroso si intende per esempio, che non è possibile forzare un intero Java in un riferimento ad oggetto o accedere alla memoria privata corrompendo i bytecodes Java. Il modello basato sulle classi di Java significa che i programmi sono composti esclusivamente da classi con i propri metodi. L'ereditarietà delle classi di Java e la tipizzazione forte di solito richiedono gerarchie di oggetti strettamente definite. Questi requisiti rendono la programmazione di Java più complessa rispetto alla programmazione di JavaScript.

+ +

D'altra parte, JavaScript si ispira ad una linea di linguaggi più piccoli, tipizzati dinamicamente come HyperTalk e dBASE. Questi linguaggi di scripting offrono strumenti di programmazione ad un pubblico più vasto grazie alla loro sintassi più facile, alle funzionalità specializzate predefinite nel linguaggio, ed ai minimi requisiti per la creazione di oggetti.

+ + + + + + + + + + + + + + + + + + + + + + + +
JavaScript confrontato con Java
JavaScriptJava
+

Orientato ad oggetti. Non c'è distinzione tra tipi di oggetti. Ereditarietà con il meccanismo dei prototype e le proprietà ed i metodi possono essere aggiunti ad ogni oggetto dinamicamente.

+
+

Basato su classi. Gli oggetti vengono distinti in classi ed istanze con tutta l'ereditarietà costruita con lagerarchia delle classi. Classi ed istanze non possono avere proprietà o metodi aggiunti dinamicamente.

+
Le variabili ed i tipi non sono dichiarati (tipizzazione dinamica).Le variabili ed i tipi di dato devono essere dichiarati (tipizzazione statica).
Non si può scrivere automaticamente suk disco fisso.Si può scrivere automaticamente su disco fisso.
+ +

Per maggiori informazioni sulle differenze tra JavaScript e Java, vedi il capitolo Dettagli sul modello ad oggetti.

+ +

JavaScript e le specifiche ECMAScript

+ +

JavaScript è standardizzato da Ecma International — l'associazione Europea per la standardizzazione dei sisteni di comunicazione ed informazione (ECMA è l'acronimo di European Computer Manufacturers Association) per distribuire linguaggio di programmazione standardizzato ed internazionale basato su JavaScript. Questa versione standardizzata di JavaScript, chiamata ECMAScript, si comporta alla stesso modo in tutte le applicazioni che supportano lo standard. Le aziende possono usare il linguaggo standard aperto per svilupare le proprie implementazioni di JavaScript. Lo standard ECMAScript è documentato nelle specifiche ECMA-262. Consulta Novità in JavaScript per conoscere di più sulle differenti versioni di JavaScript e delle edizioni delle specifiche ECMAScript.

+ +

Lo standard ECMA-262 è anche approvato da ISO (International Organization for Standardization) come ISO-16262. Si possono trovare le specifiche nel sito Ecma internazionale. Le specifiche ECMAScript non descrivono il Document Object Model (DOM), che viene standardizzato dal World Wide Web Consortium (W3C). Il DOM definisce il modo in cui gli oggetti di un documento HTML vengono esposti al tuo script. Per farti un'idea migliore sulle differenti tecnologie che si usano quando si programma con JavaScript, consulta l'articolo Panoramicha delle tecnologie JavaScript.

+ +

Documentazione JavaScript a confronto con le specifiche ECMAScript

+ +

Le specifiche ECMAScript sono una serie di requisiti per implementare ECMAScript; sono utili per chi desidera implementare funzionalità compatibili con lo standard del linguaggio nella propria implementazione di ECMAScript (come SpiderMonkey in Firefox, o v8 in Chrome).

+ +

La documentazione ECMAScript non è indirizzata ad aiutare i programmatori di script; usa la documentazione di JavaScript per informazioni su come scrivere script.

+ +

Le specifiche ECMAScript usano terminologie e sintassi che possono risultare non  familiari ai programmatori JavaScript Sebbene la descrizione del linguaggio possa essere diversa in ECMAScript, il linguaggio in se rimane lo stesso. JavaScript supporta tutte le funzionalità descritte nelle specifiche ECMAScript.

+ +

La documentazione JavaScript descrive aspetti del linguaggio che sono appropriati per il programmatore JavaScript.

+ +

Iniziare con JavaScript

+ +

Iniziare con JavaScript è facile: la sola cosa che serve è un Web browser moderno. Questa guida include alcune funzionalità di JavaScript che sono attualmente disponibili solo nell'ultima versione di Firefox, per questo raccomandiamo di usare la versione più recente di Firefox.

+ +

In Firefox sono presenti due strumenti che sono utili per sperimentare con JavaScript: la Console Web ed il Blocco per gli appunti.

+ +

La Console Web

+ +

La Console Web espone informazioni sulla pagina Web attualmente caricata, ed include una command line che si può usare per eseguire espressioni nella pagina corrente.

+ +

Per aprire la Console Web (Ctrl+Shift+K), scegli "Console web" dal menu "Sviluppo web", che si trova nel menu "Strumenti" di Firefox. Essa appare sotto la finestra del browser. Alla fine della console è presente la linea di comando che si può usare per inserire comandi JavaScript ed il risultato compare nel pannello soprastante:

+ +

+ +

Blocco per gli appunti

+ +

La Console Web è magnifica per eseguire singole linee di JavaScript, ma sebbene si possano eseguire linee multiple, non è molto comoda per questo e non è possibile salvare i propri esempi di codice con la Console Web. Quindi per esempi più complessi di codice il Blocco per gli appunti è uno strumento migliore.

+ +

Per aprire il Blocco per gli appunti (Shift+F4), scegli "Blocco per gli appunti" dal menu "Sviluppo web", che si trova nel menu "Strumenti" di Firefox. Si apre in una finestra separata ed un editor che puoi usare per scrivere ed eseguire JavaScript nel browser. Si possono anche salvare scripts nel disco e caricare scripts salvati.

+ +

+ +

Hello world

+ +

Per iniziare a scrivere programmi JavaScript, apri il Blocco per gli appunti e scrivi il tuo primo codice "Hello world" JavaScript:

+ +
function greetMe(yourName) {
+  alert("Hello " + yourName);
+}
+
+greetMe("World");
+
+ +

Seleziona il codice nel blocco e premi Ctrl+R per vedere il risultato nel browser!

+ +

Nelle prossime pagine, questa guida ti itrodurra alla sintassi di JavaScript ed alle caratteristiche del linguaggio, in questo modo sarai in grado di scrivere applicazioni più complesse.

+ +

{{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammar_and_types")}}

diff --git a/files/it/web/javascript/guide/iterators_and_generators/index.html b/files/it/web/javascript/guide/iterators_and_generators/index.html new file mode 100644 index 0000000000..49b220cdd1 --- /dev/null +++ b/files/it/web/javascript/guide/iterators_and_generators/index.html @@ -0,0 +1,162 @@ +--- +title: Iteratori e generatori +slug: Web/JavaScript/Guida/Iteratori_e_generatori +translation_of: Web/JavaScript/Guide/Iterators_and_Generators +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Meta_programming")}}
+ +

Processare ognuno degli elementi in una collezione è un'operazione molto comune. JavaScript fornisce tutta una serie di costrutti per iterare una collezione di elementi, dai semplici cicli {{jsxref("Statements/for","for")}} a {{jsxref("Global_Objects/Array/map","map()")}} e {{jsxref("Global_Objects/Array/filter","filter()")}}. Iterators e Generators portano il concetto di iterazione direttamente al cuore del linguaggio e forniscono un meccanismo per personalizzare i cicli {{jsxref("Statements/for...of","for...of")}}.

+ +

Per maggiori dettagli, vedi anche:

+ + + +

Iterators

+ +

Un oggetto è un iterator quando sa come accedere agli elementi di una collezione uno per volta, conservando l'informazione sulla sua posizione corrente nella sequenza. In Javascript un iterator è un oggetto che implementa il metodo next() , il quale ritorna l'elemento successivo della sequenza. Questo metodo ritorna un oggetto con due proprietà: done evalue.

+ +

Una volta che è stato creato, un iterator può essere utlizzato esplicitamente chiamando più volte il metodo next().

+ +
function makeIterator(array) {
+    var nextIndex = 0;
+
+    return {
+       next: function() {
+           return nextIndex < array.length ?
+               {value: array[nextIndex++], done: false} :
+               {done: true};
+       }
+    };
+}
+ +

Una volta che un iterator è stato inizializzato, il metodonext() può essere chiamato per accedere a coppie chiave-valore dall'oggetto ritornato:

+ +
var it = makeIterator(['yo', 'ya']);
+console.log(it.next().value); // 'yo'
+console.log(it.next().value); // 'ya'
+console.log(it.next().done);  // true
+ +

Generators

+ +

Nonostante implementare un iterator possa essere utile, richiede una considerevole attenzione nella programmazione a causa del bisogno esplicito di mantenere lo stato interno dell'iteratore. I {{jsxref("Global_Objects/Generator","Generators","","true")}} forniscono una potente alternativa: ti permettono di definire un algoritmo iterativo scrivendo una singola funzione in grado di mantenere il proprio stato.

+ +

Una GeneratorFunction è uno speciale tipo di funzione che opera come una "fabbrica" di iterators. Quando viene eseguita ritorna un nuovo oggetto Generator. Una funzione diventa una GeneratorFunction se usa la sintassi {{jsxref("Statements/function*","function*")}}.

+ +
function* idMaker() {
+  var index = 0;
+  while(true)
+    yield index++;
+}
+
+var gen = idMaker();
+
+console.log(gen.next().value); // 0
+console.log(gen.next().value); // 1
+console.log(gen.next().value); // 2
+// ...
+ +

Iterables

+ +

Un oggetto è un iterable se definisce un comportamento di iterazione, come per esempio quali valori sono considerati in un costrutto {{jsxref("Statements/for...of", "for...of")}}. Alcuni tipi built-in di Javascript (come {{jsxref("Array")}} o {{jsxref("Map")}}) hanno un comportamento predefinito, mentre altri tipi (come {{jsxref("Object")}}) non ce l'hanno.

+ +

Affinché un oggetto possa essere considerato un iterable deve implementare il metodo @@iterator, cioè l'oggetto (o uno degli oggetti che lo precedono nella catena dei prototipi) deve avere una proprietà con una chiave {{jsxref("Symbol.iterator")}}.

+ +

Iterables definiti dall'utente

+ +

Possiamo creare i nostri iterables in questo modo:

+ +
var myIterable = {};
+myIterable[Symbol.iterator] = function* () {
+    yield 1;
+    yield 2;
+    yield 3;
+};
+
+for (let value of myIterable) {
+    console.log(value);
+}
+// 1
+// 2
+// 3
+
+or
+
+[...myIterable]; // [1, 2, 3]
+
+ +

Iterables Built-in

+ +

{{jsxref("String")}}, {{jsxref("Array")}}, {{jsxref("TypedArray")}}, {{jsxref("Map")}} e {{jsxref("Set")}} sono tutti iterables built-in nel linguaggio, perché i loro oggetti prototipi hanno tutti un metodo {{jsxref("Symbol.iterator")}}.

+ +

Sintassi che si aspettano degli iterables

+ +

Alcuni costrutti ed espressioni si aspettano degli iterables, per esempio il ciclo {{jsxref("Statements/for...of","for-of")}}, la {{jsxref("Operators/Spread_operator","sintassi spread","","true")}}, {{jsxref("Operators/yield*","yield*")}}, e l'{{jsxref("Operators/Destructuring_assignment","assegnamento di destrutturazione","","true")}}.

+ +
for (let value of ['a', 'b', 'c']) {
+    console.log(value);
+}
+// "a"
+// "b"
+// "c"
+
+[...'abc']; // ["a", "b", "c"]
+
+function* gen() {
+  yield* ['a', 'b', 'c'];
+}
+
+gen().next(); // { value: "a", done: false }
+
+[a, b, c] = new Set(['a', 'b', 'c']);
+a; // "a"
+
+
+ +

Generators avanzati

+ +

I generators calcolano i loro valori solo quando vengono effettivamente richiesti, il che gli permette di rappresentare sequenze che sono troppo onerose da calcolare, o perfino sequenze infinite, come nella funzione idMaker().

+ +

Il metodo {{jsxref("Global_Objects/Generator/next","next()")}} accetta anche un valore che può essere utilizzato per modificare lo stato interno di un generatore. Un valore passato a next() sarà trattato come il risultato dell'ultima espressione yield che ha messo in pausa il generator.

+ +

Ecco un generator che produce una sequenza di numeri di Fibonacci. In questo generator il metodonext(x) può essere utilizzato per reinizializzare la sequenza:

+ +
function* fibonacci() {
+  var fn1 = 0;
+  var fn2 = 1;
+  while (true) {
+    var current = fn1;
+    fn1 = fn2;
+    fn2 = current + fn1;
+    var reset = yield current;
+    if (reset) {
+        fn1 = 0;
+        fn2 = 1;
+    }
+  }
+}
+
+var sequence = fibonacci();
+console.log(sequence.next().value);     // 0
+console.log(sequence.next().value);     // 1
+console.log(sequence.next().value);     // 1
+console.log(sequence.next().value);     // 2
+console.log(sequence.next().value);     // 3
+console.log(sequence.next().value);     // 5
+console.log(sequence.next().value);     // 8
+console.log(sequence.next(true).value); // 0
+console.log(sequence.next().value);     // 1
+console.log(sequence.next().value);     // 1
+console.log(sequence.next().value);     // 2
+ +

Puoi forzare un generator a lanciare una eccezione chiamando il suo metodo {{jsxref("Global_Objects/Generator/throw","throw()")}} e passandogli il valore che dovrebbe lanciare. Questa eccezione sarà lanciata dal corrente context sospeso del generator, come se lo yield che è attualmente sospeso fosse invece una dichiarazione throw value.

+ +

Se non si incontra uno yield durante la risoluzione della eccezione lanciata, allora l'eccezione si propagherà fino alla chiamata athrow(), e in tutte le successive chiamate a next() la proprietà done saràtrue.

+ +

I generators hanno un metodo {{jsxref("Global_Objects/Generator/return","return(value)")}} che ritorna un valore e termina il generator stesso.

+ +

{{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Meta_programming")}}

diff --git a/files/it/web/javascript/guide/loops_and_iteration/index.html b/files/it/web/javascript/guide/loops_and_iteration/index.html new file mode 100644 index 0000000000..c677151181 --- /dev/null +++ b/files/it/web/javascript/guide/loops_and_iteration/index.html @@ -0,0 +1,340 @@ +--- +title: Cicli e iterazioni +slug: Web/JavaScript/Guida/Loops_and_iteration +tags: + - Guide + - JavaScript + - Loop + - Sintassi +translation_of: Web/JavaScript/Guide/Loops_and_iteration +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}
+ +

I cicli offrono un modo semplice e rapido per fare cose ripetutamente. Questo capitolo della guida al JavaScript introduce i diversi metodi di iterazione disponibili in JavaScript.

+ +

Si può pensare al loop come ad una versione computerizzata di un gioco dove si dice a qualcuno di andare X passi in una direzione e Y passi in un'atra; per esempio "vai 5 passi a est" può essere espresso in questo modo con un loop:

+ +
var passi;
+for (passi = 0; passi < 5; passi++) {
+  // Viene eseguito 5 volte, con un valore di passi che va da 0 a 4.
+  console.log('Fai un passo verso est');
+}
+
+ +

Ci sono differenti tipi di ciclo, ma sono essenzialmente tutti la stessa cosa: ripetono un'azione o un insieme di azioni un certo numero di volte (è possibile che questo numero sia anche 0).

+ +

I diversi meccanismi di ciclo offrono differenti modi di determinare l'inizio e la fine del ciclo. Ci sono casi che si prestano più ad un tipo di ciclo rispetto ad altri.

+ +

Le istruzioni per i loop foriti in JavaScript sono:

+ + + +

Istruzione for

+ +

Il {{jsxref("statements/for","ciclo for")}} continua finché la condizione valutata non è falsa. Il fir loop JavaScript è simile a quello del Java e de C. L'istruzione for è definita come segue:

+ +
for ([espressioneIniziale]; [condizione]; [incremento])
+  istruzione
+
+ +

Quando viene eseguito un ciclo for, questo è ciò che accade:

+ +
    +
  1. espressioneIniziale, se esiste, viene eseguita. L'espressione di solito inizializza uno o più indici, ma la sintassi permette di scrivere espressioni con diversi gradi di compessità. Questa espressione può anche dichiarare delle variabili.
  2. +
  3. La condizione viene verificata. Se il suo valore è true, l'espressione istruzione viene eseguita. Se invece condizione è false, il ciclo finisce. Se condizione è omessa, l'espressione si assume sia true.
  4. +
  5. istruzione viene esguita. Per eseguire diverse istruzioni, è necessario usare il blocco ({ ... }) per raggrupparle.
  6. +
  7. Viene incrementata la l'espressione incremento, se esiste, eseguita, e il ciclo for va al passo successivo.
  8. +
+ +

Esempio

+ +

Il seguente esempio contiene un ciclo for che conta il numero di opzioni selezionate in una lista a scorrimento (a {{HTMLElement("select")}} che permette selezioni multiple). L'istruzione for dichiara una variabile i e la inizializza a zero. Controlla che i sia minore del numero di opzioni dell'elemento <select> , esegue l'istruzione if e incrementa i di uno alla fine di ogni ciclo.

+ +
<form name="selectForm">
+  <p>
+    <label for="musicTypes">Choose some music types, then click the button below:</label>
+    <select id="musicTypes" name="musicTypes" multiple="multiple">
+      <option selected="selected">R&B</option>
+      <option>Jazz</option>
+      <option>Blues</option>
+      <option>New Age</option>
+      <option>Classical</option>
+      <option>Opera</option>
+    </select>
+  </p>
+  <p><input id="btn" type="button" value="Quanti sono selezionati?" /></p>
+</form>
+
+<script>
+function howMany(selectObject) {
+  var numberSelected = 0;
+  for (var i = 0; i < selectObject.options.length; i++) {
+    if (selectObject.options[i].selected) {
+      numberSelected++;
+    }
+  }
+  return numberSelected;
+}
+
+var btn = document.getElementById("btn");
+btn.addEventListener("click", function(){
+  alert('Number of options selected: ' + howMany(document.selectForm.musicTypes))
+});
+</script>
+
+
+ +

Istruzione do...while

+ +

Il ciclo {{jsxref("statements/do...while", "do...while")}} si ripete finché la condizione non è falsa. Il do...while è viene definito come segue:

+ +
do
+  istruzione
+while (condizione);
+
+ +

l'istruzione viene eseguita una volta prima che la condizione venga controllata. Per eseguire più istruzioni, è necessario usare il blocco ({ ... }) . Se la condizione è vera l'istruzione viene eseguita nuovamente. Alla fine di ogni esecuzione di istruzione, condizione viene controllata. Quando condizione è falsa l'esecuzione del ciclo do..while termina.

+ +

Esempio

+ +

Nel seguente esempio il ciclo do..while itera almeno una volta e continua finché il valore di i è minore di 5.

+ +
var i = 0;
+do {
+  i += 1;
+  console.log(i);
+} while (i < 5);
+ +

Istruzione while

+ +

Il ciclo {{jsxref("statements/while","while")}} esegue un'istruzione fino a quando una condizione è true. Ecco un esempio si un ciclo while:

+ +
while (condizione)
+  istruzione   //...statement
+
+ +

Se condizione diventa false, istruzione non viene eseguita a si passa ad eseguire i comandi successivi.

+ +

Durante il ciclo condizione viene testata prima di eseguire istruzione. Se condizione è true, istruzione viene esguita e condizione viene verificata nuovamente. Se condizione è false il ciclo di ferma e viene eseguito il codice successivo al ciclo while.

+ +

Per eseguire istruzioni multiple, è necessario usare il blocco ({ ... }) così da raggruppare le istruzioni.

+ +

Esempio 1

+ +

Il seguente esempio di ciclo while si ripete fino a quando n è minore di tre:

+ +
var n = 0;
+var x = 0;
+while (n < 3) {
+  n++;
+  x += n;
+}
+
+ +

Ad ogni iterazione, il ciclo incrementa n e aggiunge quel valore a x. Pertanto,x e n assumono i seguenti valori:

+ + + +

Dopo aver completato il terzo passaggio, la condizione n < 3 non è più vera, quindi il ciclo termina.

+ +

Esempio 2

+ +

Evita loop infiniti. Assicurati che la condizione in un loop alla fine diventi falsa; altrimenti, il ciclo non terminerà mai. Le istruzioni nel seguente ciclo while vengono eseguite per sempre perché la condizione non diventa mai falsa:

+ +
+
//I loop infiniti non vanno affatto bene
+while (true) {
+  console.log("Buongiorno, Mondo");
+}
+
+ +

Istruzione "etichettata"

+ +

Un {{jsxref("statements/label","label")}} fornisce un'istruzione con un identificatore che ti consente di fare riferimento ad esso altrove nel tuo programma. Ad esempio, è possibile utilizzare un'etichetta per identificare un ciclo e quindi utilizzare le istruzioni breakcontinue per indicare se un programma deve interrompere il loop o continuare la sua esecuzione.

+ +

La sintassi dell'istruzione etichettata è simile alla seguente:

+ +
label :
+   istruzione // statement
+
+ +

Il valore dell'etichetta label può essere qualsiasi identificatore JavaScript che non sia una parola riservata. L'affermazione che ti identifichi con un'etichetta statement può essere una qualsiasi affermazione.

+ +

Esempio

+ +

In questo esempio, la label markLoop identifica un ciclo while.

+ +
markLoop:
+while (theMark == true) {
+   doSomething();
+}
+ +

Istruzione break

+ +

Utilizzare l'istruzione {{jsxref("statements/break","break")}} per terminare un ciclo, uno switch o in congiunzione con un'istruzione etichettata.

+ + + +

La sintassi dell'istruzione break è simile a questa:

+ +
break [label];
+
+ +

La prima forma della sintassi termina il ciclo switch di chiusura più interno; la seconda forma della sintassi termina l'istruzione dell'etichettata specificata.

+ +

Esempio 1

+ +

L'esempio seguente esegue iterazioni attraverso gli elementi di un array (una matrice) fino a quando non trova l'indice di un elemento il cui valore è theValue:

+ +
for (var i = 0; i < a.length; i++) {
+  if (a[i] == theValue) {
+    break;
+  }
+}
+ +

Esempio 2: Breaking to a label - Interruzione su un'etichetta

+ +
var x = 0;
+var z = 0;
+labelCancelLoops: while (true) {
+  console.log("Outer loops: " + x);
+  x += 1;
+  z = 1;
+  while (true) {
+    console.log("Inner loops: " + z);
+    z += 1;
+    if (z === 10 && x === 10) {
+      break labelCancelLoops;
+    } else if (z === 10) {
+      break;
+    }
+  }
+}
+ +

Istruzione continue

+ +

The {{jsxref("statements/continue","continue")}} statement can be used to restart a while, do-while, for, or label statement.

+ + + +

La sintassi dell'istruzione continue ha il seguente aspetto:

+ +
continue [label];
+
+ +

Esempio 1

+ +

L'esempio seguente mostra un ciclo while con un'istruzione continue che viene eseguita quando il valore di i è tre. Quindi, n assume i valori uno, tre, sette e dodici.

+ +
var i = 0;
+var n = 0;
+while (i < 5) {
+  i++;
+  if (i == 3) {
+    continue;
+  }
+  n += i;
+}
+ +

Esempio 2

+ +

Una dichiarazione etichettata checkiandj contiene una dichiarazione etichettata checkj. Se si incontra continue il programma termina l'iterazione corrente di checkj e inizia la successiva iterazione. Ogni volta che si incontra continue, checkj viene reiterato finché la condizione non restituisce false. Quando viene restituito false, il resto dell'istruzione checkiandj è completato e checkiandj reiterate fino a quando la condizione non restituisce false. Quando viene restituito false, il programma continua con la seguente istruzione checkiandj.

+ +

Se continue ha un'etichetta di checkiandj, il programma continuerà nella parte superiore del checkiandj istruzione.

+ +
var i = 0;
+var j = 10;
+checkiandj:
+  while (i < 4) {
+    console.log(i);
+    i += 1;
+    checkj:
+      while (j > 4) {
+        console.log(j);
+        j -= 1;
+        if ((j % 2) == 0) {
+          continue checkj;
+        }
+        console.log(j + ' is odd.');
+      }
+      console.log('i = ' + i);
+      console.log('j = ' + j);
+}
+ +

Istruzione for...in

+ +

L'istruzione {{jsxref("statements/for...in","for...in")}} itera una variabile specificata su tutte le proprietà enumerabili di un oggetto. Per ogni proprietà distinta, JavaScript esegue le istruzioni specificate. L'istruzione for...in ha il seguente aspetto:

+ +
for (variabile in oggetto) {
+  istruzione
+}
+// for (variable in object) {
+//  statements
+// }
+
+ +

Esempio

+ +

La seguente funzione prende come argomento un oggetto e il nome dell'oggetto. Quindi itera su tutte le proprietà dell'oggetto e restituisce una stringa che elenca i nomi delle proprietà e i loro valori.

+ +
function dump_props(obj, obj_name) {
+  var result = "";
+  for (var i in obj) {
+    result += obj_name + "." + i + " = " + obj[i] + "<br>";
+  }
+  result += "<hr>";
+  return result;
+}
+
+ +

Per un oggetto car con proprietà make e model, result sarebbe:

+ +
car.make = Ford
+car.model = Mustang
+
+ +

Arrays / Matrici

+ +

Anche se può essere allettante usarla come un modo per iterare sugli elementi {{jsxref("Array")}} , l'istruzione the for...in restituirà il nome delle proprietà definite dall'utente oltre agli indici numerici. Quindi è meglio usare un ciclo tradizionale {{jsxref("statements/for","for")}} con un indice numerico quando si itera su array, perché l'istruzione for...in itera sulle proprietà definite dall'utente oltre agli elementi dell'array, se si modifica l'oggetto Array, (come ad esempio l'aggiunta di proprietà o metodi personalizzati).

+ +

Istruzione for...of

+ +

L'istruzione {{jsxref("statements/for...of","for...of")}} crea un ciclo che itera su oggetti iterabili (inclusi oggetti di tipo {{jsxref("Array")}}, {{jsxref("Map")}}, {{jsxref("Set")}}, {{jsxref("functions/arguments","arguments")}} e così via), richiamando un aggancio di iterazione personalizzato con istruzioni da eseguire per il valore di ogni proprietà distinta.

+ +
for (variabile di oggetto) {
+  istruzione
+}
+ +

Il seguente esempio mostra la differenza tra un ciclo for...of e un {{jsxref("statements/for...in","for...in")}} ciclo continuo. Mentre for...in itera sopra i nomi delle proprietà, for...of itera sui valori delle proprietà:

+ +
let arr = [3, 5, 7];
+arr.foo = "hello";
+
+for (let i in arr) {
+   console.log(i); // logs "0", "1", "2", "foo"
+}
+
+for (let i of arr) {
+   console.log(i); // logs "3", "5", "7"
+}
+ +

{{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}

diff --git a/files/it/web/javascript/guide/regular_expressions/index.html b/files/it/web/javascript/guide/regular_expressions/index.html new file mode 100644 index 0000000000..f876045948 --- /dev/null +++ b/files/it/web/javascript/guide/regular_expressions/index.html @@ -0,0 +1,647 @@ +--- +title: Espressioni regolari +slug: Web/JavaScript/Guida/Espressioni_Regolari +translation_of: Web/JavaScript/Guide/Regular_Expressions +--- +
{{jsSidebar("Guida JavaScript")}} {{PreviousNext("Web/JavaScript/Guide/Text_formatting", "Web/JavaScript/Guide/Indexed_collections")}}
+ +

Le espressioni regolari sono schemi usati per confrontare combinazioni di caratteri nelle stringhe. In JavaScript, le espressioni regolari sono anche oggetti. Questi pattern sono usati con i metodi {{jsxref("RegExp.exec", "exec()")}} e {{jsxref("RegExp.test", "test()")}} della classe {{jsxref("RegExp")}}, e con i metodi {{jsxref("String.match", "match()")}},   {{jsxref("String.matchAll", "matchAll()")}}, {{jsxref("String.replace", "replace()")}}, {{jsxref("String.search", "search()")}}, e {{jsxref("String.split", "split()")}} della classe {{jsxref("String")}}. Questo capitolo descrive le espressioni regolari in JavaScript.

+ +

Creazione di un'espressione regolare

+ +

Puoi creare un'espressione regolare in uno dei seguenti modi:

+ + + +

Scrivere uno schema per espressioni regolari

+ +

Uno schema di espressione regolare è composto da caratteri semplici, come /abc/, o da una combinazione di caratteri semplici e speciali, come /ab*c//Chapter (\d+)\.\d*/. L'ultimo esempio include parentesi che sono usate come un dispositivo di memoria. Il confronto fatto con queste parti dello schema è ricordato per usi futuri, come descritto in  {{ web.link("#Using_parenthesized_substring_matches", "Using parenthesized substring matches") }}.

+ +
+

Nota: Se hai già familiarità con la struttura di un'espressione regolare, potresti anche leggere il cheatsheet per una rapida ricerca di un modello/costrutto specifico

+
+ +

Usare modelli semplici

+ +

I modelli semplici sono costituiti da carattrei per i quali si desidera trovare una corrispondenza diretta. Ad esempio, il modello /abc/ corrisponde solo quando esattamente i caratteri "abc" si presentano insieme e in quell'ordine. Una tale corrispondenza avrebbe successo nelle stringhe "Ciao, conosci il tuo abc?" e "Gli ultimi progetti di aeroplani si sono evoluti da slabcraft". In entrambi i casi la corrispondenza con la sottostringa "abc" avviene. Non c'è corrispondenza nella stringa "Grab crab" perché invece di contenere l'esatta sottostringa "abc" coniente la sottostringa "ab c".

+ +

Usare caratteri speciali

+ +

Quando la ricerca di una corrispondenza richiede qualcosa di più di una corrispondenza diretta, come la ricerca di una o più b o la ricerca di spazi bianchi, il modello include caratteri speciali. Ad esempio, per abbinare una singola "a" seguita da zero o più "b" seguita da "c", dovresti usare il modello /ab*c/: il * dopo "b" significa "0 o più occorrenze dell'elemento precedente". Nella stringa "cbbabbbbcdebc", questo modello corrisponderà alla sottostringa "abbbbc".
+
+ La tabella seguente fornisce un elenco completo e una descrizione dei caratteri speciali che possono essere utilizzati nelle espressioni regolari.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Caratteri speciali nelle espressioni regolari
CarattereSignificato/Utilizzo
\ +

Matches according to the following rules:
+
+ A backslash that precedes a non-special character indicates that the next character is special and is not to be interpreted literally. For example, a 'b' without a preceding '\' generally matches lowercase 'b's wherever they occur. But a '\b' by itself doesn't match any character; it forms the special word boundary character.
+
+ A backslash that precedes a special character indicates that the next character is not special and should be interpreted literally. For example, the pattern /a*/ relies on the special character '*' to match 0 or more a's. By contrast, the pattern /a\*/ removes the specialness of the '*' to enable matches with strings like 'a*'.
+
+ Do not forget to escape \ itself while using the RegExp("pattern") notation because \ is also an escape character in strings.

+
^Matches beginning of input. If the multiline flag is set to true, also matches immediately after a line break character.
+
+ For example, /^A/ does not match the 'A' in "an A", but does match the 'A' in "An E".
+
+ The '^' has a different meaning when it appears as the first character in a character set pattern. See complemented character sets for details and an example.
$ +

Matches end of input. If the multiline flag is set to true, also matches immediately before a line break character.

+ +

For example, /t$/ does not match the 't' in "eater", but does match it in "eat".

+
* +

Matches the preceding expression 0 or more times. Equivalent to {0,}.

+ +

For example, /bo*/ matches 'boooo' in "A ghost booooed" and 'b' in "A bird warbled", but nothing in "A goat grunted".

+
+ +

Matches the preceding expression 1 or more times. Equivalent to {1,}.

+ +

For example, /a+/ matches the 'a' in "candy" and all the a's in "caaaaaaandy", but nothing in "cndy".

+
?Matches the preceding expression 0 or 1 time. Equivalent to {0,1}.
+
+ For example, /e?le?/ matches the 'el' in "angel" and the 'le' in "angle" and also the 'l' in "oslo".
+
+ If used immediately after any of the quantifiers *, +, ?, or {}, makes the quantifier non-greedy (matching the fewest possible characters), as opposed to the default, which is greedy (matching as many characters as possible). For example, applying /\d+/ to "123abc" matches "123". But applying /\d+?/ to that same string matches only the "1".
+
+ Also used in lookahead assertions, as described in the x(?=y) and x(?!y) entries of this table.
+  
. +

(The decimal point) matches any single character except the newline character.

+ +

For example, /.n/ matches 'an' and 'on' in "nay, an apple is on the tree", but not 'nay'.

+
(x) +

Matches 'x' and remembers the match, as the following example shows. The parentheses are called capturing parentheses.
+
+ The '(foo)' and '(bar)' in the pattern /(foo) (bar) \1 \2/ match and remember the first two words in the string "foo bar foo bar". The \1 and \2 in the pattern match the string's last two words. Note that \1, \2, \n are used in the matching part of the regex. In the replacement part of a regex the syntax $1, $2, $n must be used, e.g.: 'bar foo'.replace( /(...) (...)/, '$2 $1' ).

+
(?:x)Matches 'x' but does not remember the match. The parentheses are called non-capturing parentheses, and let you define subexpressions for regular expression operators to work with. Consider the sample expression /(?:foo){1,2}/. If the expression was /foo{1,2}/, the {1,2} characters would apply only to the last 'o' in 'foo'. With the non-capturing parentheses, the {1,2} applies to the entire word 'foo'.
x(?=y) +

Matches 'x' only if 'x' is followed by 'y'. This is called a lookahead.

+ +

For example, /Jack(?=Sprat)/ matches 'Jack' only if it is followed by 'Sprat'. /Jack(?=Sprat|Frost)/ matches 'Jack' only if it is followed by 'Sprat' or 'Frost'. However, neither 'Sprat' nor 'Frost' is part of the match results.

+
x(?!y) +

Matches 'x' only if 'x' is not followed by 'y'. This is called a negated lookahead.

+ +

For example, /\d+(?!\.)/ matches a number only if it is not followed by a decimal point. The regular expression /\d+(?!\.)/.exec("3.141") matches '141' but not '3.141'.

+
x|y +

Matches either 'x' or 'y'.

+ +

For example, /green|red/ matches 'green' in "green apple" and 'red' in "red apple."

+
{n}Matches exactly n occurrences of the preceding expression. N must be a positive integer.
+
+ For example, /a{2}/ doesn't match the 'a' in "candy," but it does match all of the a's in "caandy," and the first two a's in "caaandy."
{n,m} +

Where n and m are positive integers and n <= m. Matches at least n and at most m occurrences of the preceding expression. When m is omitted, it's treated as ∞.

+ +

For example, /a{1,3}/ matches nothing in "cndy", the 'a' in "candy," the first two a's in "caandy," and the first three a's in "caaaaaaandy". Notice that when matching "caaaaaaandy", the match is "aaa", even though the original string had more a's in it.

+
[xyz]Character set. This pattern type matches any one of the characters in the brackets, including escape sequences. Special characters like the dot(.) and asterisk (*) are not special inside a character set, so they don't need to be escaped. You can specify a range of characters by using a hyphen, as the following examples illustrate.
+
+ The pattern [a-d], which performs the same match as [abcd], matches the 'b' in "brisket" and the 'c' in "city". The patterns /[a-z.]+/ and /[\w.]+/ match the entire string "test.i.ng".
[^xyz] +

A negated or complemented character set. That is, it matches anything that is not enclosed in the brackets. You can specify a range of characters by using a hyphen. Everything that works in the normal character set also works here.

+ +

For example, [^abc] is the same as [^a-c]. They initially match 'r' in "brisket" and 'h' in "chop."

+
[\b]Matches a backspace (U+0008). You need to use square brackets if you want to match a literal backspace character. (Not to be confused with \b.)
\b +

Matches a word boundary. A word boundary matches the position where a word character is not followed or preceeded by another word-character. Note that a matched word boundary is not included in the match. In other words, the length of a matched word boundary is zero. (Not to be confused with [\b].)

+ +

Examples:
+ /\bm/ matches the 'm' in "moon" ;
+ /oo\b/ does not match the 'oo' in "moon", because 'oo' is followed by 'n' which is a word character;
+ /oon\b/ matches the 'oon' in "moon", because 'oon' is the end of the string, thus not followed by a word character;
+ /\w\b\w/ will never match anything, because a word character can never be followed by both a non-word and a word character.

+ +
+

Note: JavaScript's regular expression engine defines a specific set of characters to be "word" characters. Any character not in that set is considered a word break. This set of characters is fairly limited: it consists solely of the Roman alphabet in both upper- and lower-case, decimal digits, and the underscore character. Accented characters, such as "é" or "ü" are, unfortunately, treated as word breaks.

+
+
\B +

Matches a non-word boundary. This matches a position where the previous and next character are of the same type: Either both must be words, or both must be non-words. The beginning and end of a string are considered non-words.

+ +

For example, /\B../ matches 'oo' in "noonday", and /y\B./ matches 'ye' in "possibly yesterday."

+
\cX +

Where X is a character ranging from A to Z. Matches a control character in a string.

+ +

For example, /\cM/ matches control-M (U+000D) in a string.

+
\d +

Matches a digit character. Equivalent to [0-9].

+ +

For example, /\d/ or /[0-9]/ matches '2' in "B2 is the suite number."

+
\D +

Matches any non-digit character. Equivalent to [^0-9].

+ +

For example, /\D/ or /[^0-9]/ matches 'B' in "B2 is the suite number."

+
\fMatches a form feed (U+000C).
\nMatches a line feed (U+000A).
\rMatches a carriage return (U+000D).
\s +

Matches a single white space character, including space, tab, form feed, line feed. Equivalent to [ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff].

+ +

For example, /\s\w*/ matches ' bar' in "foo bar."

+
\S +

Matches a single character other than white space. Equivalent to [^ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff].

+ +

For example, /\S\w*/ matches 'foo' in "foo bar."

+
\tMatches a tab (U+0009).
\vMatches a vertical tab (U+000B).
\w +

Matches any alphanumeric character including the underscore. Equivalent to [A-Za-z0-9_].

+ +

For example, /\w/ matches 'a' in "apple," '5' in "$5.28," and '3' in "3D."

+
\W +

Matches any non-word character. Equivalent to [^A-Za-z0-9_].

+ +

For example, /\W/ or /[^A-Za-z0-9_]/ matches '%' in "50%."

+
\n +

Where n is a positive integer, a back reference to the last substring matching the n parenthetical in the regular expression (counting left parentheses).

+ +

For example, /apple(,)\sorange\1/ matches 'apple, orange,' in "apple, orange, cherry, peach."

+
\0Matches a NULL (U+0000) character. Do not follow this with another digit, because \0<digits> is an octal escape sequence.
\xhhMatches the character with the code hh (two hexadecimal digits)
\uhhhhMatches the character with the code hhhh (four hexadecimal digits).
\u{hhhh}(only when u flag is set) Matches the character with the Unicode value hhhh (hexadecimal digits).
+ +

Escaping user input to be treated as a literal string within a regular expression can be accomplished by simple replacement:

+ +
function escapeRegExp(string){
+  return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
+}
+ +

Using parentheses

+ +

Parentheses around any part of the regular expression pattern cause that part of the matched substring to be remembered. Once remembered, the substring can be recalled for other use, as described in {{ web.link("#Using_parenthesized_substring_matches", "Using Parenthesized Substring Matches") }}.

+ +

For example, the pattern /Chapter (\d+)\.\d*/ illustrates additional escaped and special characters and indicates that part of the pattern should be remembered. It matches precisely the characters 'Chapter ' followed by one or more numeric characters (\d means any numeric character and + means 1 or more times), followed by a decimal point (which in itself is a special character; preceding the decimal point with \ means the pattern must look for the literal character '.'), followed by any numeric character 0 or more times (\d means numeric character, * means 0 or more times). In addition, parentheses are used to remember the first matched numeric characters.

+ +

This pattern is found in "Open Chapter 4.3, paragraph 6" and '4' is remembered. The pattern is not found in "Chapter 3 and 4", because that string does not have a period after the '3'.

+ +

To match a substring without causing the matched part to be remembered, within the parentheses preface the pattern with ?:. For example, (?:\d+) matches one or more numeric characters but does not remember the matched characters.

+ +

Lavorare con le espressioni regolari

+ +

Le espressioni regolari sono usate con i metodi test and exec di RegExp e con i metodi match, replace, search, and split di String .Questi metodi sono spiegati in dettaglio nelle  JavaScript reference.

+ +

Metodi che usano le espressioni regolari

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MetodoDescrizione
{{jsxref("RegExp.exec", "exec")}} +

Un metodo di RegExp che esegue una ricerca per una corrispondenza in una stringa. Ritorna un array di informazioni, o null se non trova corrispondenze.

+
{{jsxref("RegExp.test", "test")}}Un metodo di RegExp che testa le corrispondenze in una stinga. Ritorna true o false. 
{{jsxref("String.match", "match")}}Un metodo di String che esegue una ricerca per una corrispondenza in una stringa. Ritorna un array di informazioni, o null se non trova corrispondenze.
{{jsxref("String.search", "search")}}A String method that tests for a match in a string. It returns the index of the match, or -1 if the search fails.
{{jsxref("String.replace", "replace")}}A String method that executes a search for a match in a string, and replaces the matched substring with a replacement substring.
{{jsxref("String.split", "split")}}A String method that uses a regular expression or a fixed string to break a string into an array of substrings.
+ +

When you want to know whether a pattern is found in a string, use the test or search method; for more information (but slower execution) use the exec or match methods. If you use exec or match and if the match succeeds, these methods return an array and update properties of the associated regular expression object and also of the predefined regular expression object, RegExp. If the match fails, the exec method returns null (which coerces to false).

+ +

In the following example, the script uses the exec method to find a match in a string.

+ +
var myRe = /d(b+)d/g;
+var myArray = myRe.exec("cdbbdbsbz");
+
+ +

If you do not need to access the properties of the regular expression, an alternative way of creating myArray is with this script:

+ +
var myArray = /d(b+)d/g.exec("cdbbdbsbz"); // equivalent to "cdbbdbsbz".match(/d(b+)d/g);
+
+ +

If you want to construct the regular expression from a string, yet another alternative is this script:

+ +
var myRe = new RegExp("d(b+)d", "g");
+var myArray = myRe.exec("cdbbdbsbz");
+
+ +

With these scripts, the match succeeds and returns the array and updates the properties shown in the following table.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Results of regular expression execution.
ObjectProperty or indexDescriptionIn this example
myArrayThe matched string and all remembered substrings.["dbbd", "bb"]
indexThe 0-based index of the match in the input string.1
inputThe original string."cdbbdbsbz"
[0]The last matched characters."dbbd"
myRelastIndexThe index at which to start the next match. (This property is set only if the regular expression uses the g option, described in {{ web.link("#Advanced_searching_with_flags", "Advanced Searching With Flags") }}.)5
sourceThe text of the pattern. Updated at the time that the regular expression is created, not executed."d(b+)d"
+ +

As shown in the second form of this example, you can use a regular expression created with an object initializer without assigning it to a variable. If you do, however, every occurrence is a new regular expression. For this reason, if you use this form without assigning it to a variable, you cannot subsequently access the properties of that regular expression. For example, assume you have this script:

+ +
var myRe = /d(b+)d/g;
+var myArray = myRe.exec("cdbbdbsbz");
+console.log("The value of lastIndex is " + myRe.lastIndex);
+
+// "The value of lastIndex is 5"
+
+ +

However, if you have this script:

+ +
var myArray = /d(b+)d/g.exec("cdbbdbsbz");
+console.log("The value of lastIndex is " + /d(b+)d/g.lastIndex);
+
+// "The value of lastIndex is 0"
+
+ +

The occurrences of /d(b+)d/g in the two statements are different regular expression objects and hence have different values for their lastIndex property. If you need to access the properties of a regular expression created with an object initializer, you should first assign it to a variable.

+ +

Using parenthesized substring matches

+ +

Including parentheses in a regular expression pattern causes the corresponding submatch to be remembered. For example, /a(b)c/ matches the characters 'abc' and remembers 'b'. To recall these parenthesized substring matches, use the Array elements [1], ..., [n].

+ +

The number of possible parenthesized substrings is unlimited. The returned array holds all that were found. The following examples illustrate how to use parenthesized substring matches.

+ +

The following script uses the {{jsxref("String.replace", "replace()")}} method to switch the words in the string. For the replacement text, the script uses the $1 and $2 in the replacement to denote the first and second parenthesized substring matches.

+ +
var re = /(\w+)\s(\w+)/;
+var str = "John Smith";
+var newstr = str.replace(re, "$2, $1");
+console.log(newstr);
+
+ +

This prints "Smith, John".

+ +

Advanced searching with flags

+ +

Regular expressions have four optional flags that allow for global and case insensitive searching. These flags can be used separately or together in any order, and are included as part of the regular expression.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Regular expression flags
FlagDescription
gGlobal search.
iCase-insensitive search.
mMulti-line search.
yPerform a "sticky" search that matches starting at the current position in the target string. See {{jsxref("RegExp.sticky", "sticky")}}
+ +

To include a flag with the regular expression, use this syntax:

+ +
var re = /pattern/flags;
+
+ +

or

+ +
var re = new RegExp("pattern", "flags");
+
+ +

Note that the flags are an integral part of a regular expression. They cannot be added or removed later.

+ +

For example, re = /\w+\s/g creates a regular expression that looks for one or more characters followed by a space, and it looks for this combination throughout the string.

+ +
var re = /\w+\s/g;
+var str = "fee fi fo fum";
+var myArray = str.match(re);
+console.log(myArray);
+
+ +

This displays ["fee ", "fi ", "fo "]. In this example, you could replace the line:

+ +
var re = /\w+\s/g;
+
+ +

with:

+ +
var re = new RegExp("\\w+\\s", "g");
+
+ +

and get the same result.

+ +

The m flag is used to specify that a multiline input string should be treated as multiple lines. If the m flag is used, ^ and $ match at the start or end of any line within the input string instead of the start or end of the entire string.

+ +

Examples

+ +

The following examples show some uses of regular expressions.

+ +

Changing the order in an input string

+ +

The following example illustrates the formation of regular expressions and the use of string.split() and string.replace(). It cleans a roughly formatted input string containing names (first name first) separated by blanks, tabs and exactly one semicolon. Finally, it reverses the name order (last name first) and sorts the list.

+ +
// The name string contains multiple spaces and tabs,
+// and may have multiple spaces between first and last names.
+var names = "Harry Trump ;Fred Barney; Helen Rigby ; Bill Abel ; Chris Hand ";
+
+var output = ["---------- Original String\n", names + "\n"];
+
+// Prepare two regular expression patterns and array storage.
+// Split the string into array elements.
+
+// pattern: possible white space then semicolon then possible white space
+var pattern = /\s*;\s*/;
+
+// Break the string into pieces separated by the pattern above and
+// store the pieces in an array called nameList
+var nameList = names.split(pattern);
+
+// new pattern: one or more characters then spaces then characters.
+// Use parentheses to "memorize" portions of the pattern.
+// The memorized portions are referred to later.
+pattern = /(\w+)\s+(\w+)/;
+
+// New array for holding names being processed.
+var bySurnameList = [];
+
+// Display the name array and populate the new array
+// with comma-separated names, last first.
+//
+// The replace method removes anything matching the pattern
+// and replaces it with the memorized string—second memorized portion
+// followed by comma space followed by first memorized portion.
+//
+// The variables $1 and $2 refer to the portions
+// memorized while matching the pattern.
+
+output.push("---------- After Split by Regular Expression");
+
+var i, len;
+for (i = 0, len = nameList.length; i < len; i++){
+  output.push(nameList[i]);
+  bySurnameList[i] = nameList[i].replace(pattern, "$2, $1");
+}
+
+// Display the new array.
+output.push("---------- Names Reversed");
+for (i = 0, len = bySurnameList.length; i < len; i++){
+  output.push(bySurnameList[i]);
+}
+
+// Sort by last name, then display the sorted array.
+bySurnameList.sort();
+output.push("---------- Sorted");
+for (i = 0, len = bySurnameList.length; i < len; i++){
+  output.push(bySurnameList[i]);
+}
+
+output.push("---------- End");
+
+console.log(output.join("\n"));
+
+ +

Using special characters to verify input

+ +

In the following example, the user is expected to enter a phone number. When the user presses the "Check" button, the script checks the validity of the number. If the number is valid (matches the character sequence specified by the regular expression), the script shows a message thanking the user and confirming the number. If the number is invalid, the script informs the user that the phone number is not valid.

+ +

Within non-capturing parentheses (?: , the regular expression looks for three numeric characters \d{3} OR | a left parenthesis \( followed by three digits \d{3}, followed by a close parenthesis \), (end non-capturing parenthesis )), followed by one dash, forward slash, or decimal point and when found, remember the character ([-\/\.]), followed by three digits \d{3}, followed by the remembered match of a dash, forward slash, or decimal point \1, followed by four digits \d{4}.

+ +

The Change event activated when the user presses Enter sets the value of RegExp.input.

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+    <meta http-equiv="Content-Script-Type" content="text/javascript">
+    <script type="text/javascript">
+      var re = /(?:\d{3}|\(\d{3}\))([-\/\.])\d{3}\1\d{4}/;
+      function testInfo(phoneInput){
+        var OK = re.exec(phoneInput.value);
+        if (!OK)
+          window.alert(phoneInput.value + " isn't a phone number with area code!");
+        else
+          window.alert("Thanks, your phone number is " + OK[0]);
+      }
+    </script>
+  </head>
+  <body>
+    <p>Enter your phone number (with area code) and then click "Check".
+        <br>The expected format is like ###-###-####.</p>
+    <form action="#">
+      <input id="phone"><button onclick="testInfo(document.getElementById('phone'));">Check</button>
+    </form>
+  </body>
+</html>
+
+ +
{{PreviousNext("Web/JavaScript/Guide/Text_formatting", "Web/JavaScript/Guide/Indexed_collections")}}
diff --git a/files/it/web/javascript/il_dom_e_javascript/index.html b/files/it/web/javascript/il_dom_e_javascript/index.html deleted file mode 100644 index 9f2b0fbb56..0000000000 --- a/files/it/web/javascript/il_dom_e_javascript/index.html +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: Il DOM e JavaScript -slug: Web/JavaScript/Il_DOM_e_JavaScript -tags: - - DOM - - JavaScript - - Tutte_le_categorie -translation_of: Web/JavaScript/JavaScript_technologies_overview ---- -

Il Grande Disegno

- -

Gli effetti visivi come muovere i layer sulla pagina, mostrare e nascondere layer, far comparire menu, eccetera, sono spesso indicati come "DHTML", o "Dynamic HTML". Alcuni hanno dubbi sull'effettiva utilità di queste tecnologie in pagine web che dovrebbero trasmettere del contenuto e non la presentazione, ma dobbiamo comunque prendere atto della loro larga diffusione.

- -

Molti web master si limitano ad andare sui siti che offrono script DHTML e ricopiare il codice nelle loro pagine, senza interessarsi a come funzionano quegli script DHTML. Sfortunatamente la maggior parte di questi siti parlano di "javascript" e "DHTML", ma mai di DOM, il quale, sebbene sia un concetto introdotto da parecchio, solo di recente sta entrando nel gergo del web designer medio.

- -

E' una grande sfida per un progetto come Mozilla convincere i possessori di questi siti che ***it is worth coding for the W3C DOM, which sometimes means a lot of work, and drops support for the older browsers. It is also a big challenge to get the facts straight concerning the support for the W3C DOM. *** Uno dei più grandi problemi che incontrano alcuni web developer è la confusione tra JavaScript, DHTML e il DOM. In questo articolo tenteremo di chiarire le cose, e di spiegare le relazioni fra queste utili ed elaborate tecnologie.

- -

JavaScript, IL Linguaggio di Web Scripting

- -

JavaScript è un "linguaggio di scripting di oggetti" sviluppato inizialmente alla Netscape Communications Corp. da Brendan Eich, che oggi è uno dei leader del progetto Mozilla. Il motore JavaScript usato da Mozilla si chiama SpiderMonkey, e aderisce alla specifica ECMA-262 3°revisione(di cui è un superset; guarda anche la pagina ECMAScript).

- -

Contrariamente a diffuse errate credenze, JavaScript non è "Java Interpretato". Possiamo dire che JavaScript è un linguaggio di scripting dinamico che supporta la costruzione di oggetti basata su prototipi. La sintassi di base è volutamente simile sia a Java che a C++ per ridurre il numero di nuovi concetti richiesti per imparare il linguaggio. Il grande vantaggio di JavaScript è che è estremamente facile da imparare se vuoi fare programmazione di base (come quella richiesta per semplici DHTML). Niente tipi di variabili a vista, stringhe semplici da usare, neutralità totale della piattaforma,ecc. Per i programmatori avanzati può essere usato sia come linguaggio orientato agli oggetti che come linguaggio procedurale.

- -

Gran parte di questo paragrafo su JavaScript è stato preso dalla pagina JavaScript di Mozilla. Puoi anche consultare la più recente specifica ECMA.

- -

Il Modello a Oggetti del Documento, un insieme di interfacce indipendenti dal linguaggio

- -

Mentre Javascript è il linguaggio di programmazione che ti permette di operare sugli oggetti DOM, il DOM ti fornisce metodi e proprietà per recuperare, modificare, aggiornare ed eliminare parti del documento su cui stai lavorando. Per esempio, potresti recuperare il valore di un campo di testo e metterlo in una variabile stringa con il DOM; a questo punto puoi usare l'operatore Javascript di concatenazione + , per unire quella stringa ad un'altra, in base a ciò che vuoi ottenere. Potresti quindi usare il metodo alert() per mostrare la stringa all'utente attraverso una finestra di dialogo. Guarda anche gli altri esempi più sotto.

- -

In che senso "indipendente dal linguaggio"? Non è javascript l'unico modo per accedere al DOM? No, ad esempio Mozilla usa il DOM sia col C++ che col Javascript per la sua interfaccia utente. Questi sono alcuni dei linguaggi che hanno un'implementazione del DOM: Perl, Java, ActiveX, Python; ciò è possibile grazie all'indipendenza del DOM dal linguaggio di programmazione.

- -

Il DOM e Javascript - Chi sta facendo cosa?

- -

Arriviamo al punto principale di questo documento: chi sta facendo cosa? In uno script che ho inserito nella mia pagina, dov'è il DOM, e dov'è Javascript? Guardiamo da vicino un piccolo esempio: il codice prende tutti i tag <a> della pagina e li mette in una NodeList che abbiamo chiamato "anchorTags". Quindi per ogni tag ancora facciamo comparire un avviso contenente il valore dell'attributo href del tag. In blu c'è Javascript, in rosso il DOM.

- -
var anchorTags = document.getElementsByTagName("a");
-for (var i = 0; i < anchorTags.length ; i++)
-{
-   alert("Href of " + i + "-th element is : " + anchorTags[i].href + "\n");
-}
-
- -

Spiegazione

- -

Questo frammento di codice mostra cos'è Javascript, e cos'è DOM..

- -
-
var anchorTags =
-
Crea una variabile chiamata "anchorTags".
-
document.getElementsByTagName("a")
-
L'interfaccia Document è la prima interfaccia definita nel DOM1 Core, e document è l'oggetto che implementa l'interfaccia Document. L'oggetto document contiene tutto ciò che c'è nella pagina.
- Il DOM1 Core definisce il metodo getElementsByTagName() Nell'interfaccia Document. Questo metodo mette in una NodeList(una sorta di array specifico per contenere i nodi del DOM)tutti i tag il cui nome corrisponde al parametro passato alla funzione, in ordine di apparizione nel codice sorgente del documento. La variabile anchorTags è quindi ora una NodeList.
-
;
-
Il punto e virgola che chiude le istruzioni. Roba di Javascript.
-
for (var i = 0; i <
-
Tipico ciclo "for" in un linguaggio di programmazione. Ci consente di scorrere tutti i nodi contenuto nella NodeList salvata in anchorTags. "i" è una variabile temporanea di Javascript.
-
anchorTags.length
-
Nel DOM1 Core è definita la proprietà length dell'interfaccia NodeList. Restituisce un intero che è il numero di nodi contenuti nella NodeList.
-
; i++) {
-
Tipica istruzione per incrementare di 1 una variabile. Javascript.
-
alert(
-
alert() è un metodo del DOM che apre una finestrella in mezzo allo schermo con dentro la stringa che gli hai passato. Nota: questo metodo fa parte di ciò che viene chiamato DOM level 0, o DOM0; è un insieme di interfacce che non fanno parte di nessuna specifica DOM, ma sono comunque implementate da alcuni browser.
-
"Href of this a element is : " +
-
Una stringa letterale e un operatore di concatenazione di stringhe. JavaScript.
-
anchorTags{{ mediawiki.external('i') }}.href
-
"href" è una proprietà definita dall'intefaccia HTMLAnchorElement della specifica DOM1 HTML. Restituisce il valore dell'attributo href dell'elemento ancora, se presente.
- Usiamo anche anchorTags{{ mediawiki.external('i') }}, la stessa sintassi usata in Javascript per accedere all'i-esimo elemento di un array. Un modo più "linguaggio-indipendente" per accedere a un elemento di una NodeList è l'uso del metodo item(), definito nella interfaccia NodeList: anchorTags.item(1).href, ma la maggior parte delle implementazioni Javascript permettono di usare la più sbrigativa sintassi per array, che è ciò che la maggior parte dei programmatori usano.
-
+ "\n");
-
Un'altra concatenazione di stringhe. Inserisce un ritorno del carrello alla fine della stringa.
-
}
-
Fine del ciclo "for".
-
- -
-

Original Document Information

- - -
diff --git a/files/it/web/javascript/introduzione_al_carattere_object-oriented_di_javascript/index.html b/files/it/web/javascript/introduzione_al_carattere_object-oriented_di_javascript/index.html deleted file mode 100644 index 6281d7ef4b..0000000000 --- a/files/it/web/javascript/introduzione_al_carattere_object-oriented_di_javascript/index.html +++ /dev/null @@ -1,391 +0,0 @@ ---- -title: Introduzione a JavaScript Object-Oriented -slug: Web/JavaScript/Introduzione_al_carattere_Object-Oriented_di_JavaScript -tags: - - Classe - - Costruttore - - Eredità - - Incapsulamento - - Membri - - Oggetto - - Orientato agli oggetti -translation_of: Learn/JavaScript/Objects -translation_of_original: Web/JavaScript/Introduction_to_Object-Oriented_JavaScript ---- -

{{jsSidebar("Introductory")}}

- -

Orientato agli oggetti fino dal nucleo, JavaScript offre funzionalità {{Glossary("OOP")}} potenti e flessibili. Questo articolo inizia con una introduzione alla programmazione orientata agli oggetti, quindi presenta il modello di oggetti JavaScript e, infine, dimostra concetti della programmazione orientata agli oggetti in JavaScript.

- -

Riesame su JavaScript

- -

Se non ti senti sicuro su concetti JavaScript come variabili, tipi, funzioni e ambito di applicazione, puoi leggere su questi argomenti in A re-introduction to JavaScript. Puoi inoltre consultare la Core JavaScript 1.5 Guide.

- -

Programmazione object-oriented

- -

La programmazione orientata agli oggetti è un paradigma di programmazione che usa astrazione ({{glossary("abstraction")}}) per creare modelli basati sul mondo reale. Utilizza diverse tecniche di paradigmi esistenti, tra cui la modularità ({{glossary("modularity")}}), il polimorfismo ({{glossary("polymorphism")}}) e l'incapsulamento ({{glossary("encapsulation")}}). Oggi molti linguaggi di programmazione (come Java, JavaScript, C #, C ++, Python, PHP, Ruby e Objective-C) supportano la programmazione orientata agli oggetti (OOP).

- -

OOP ha una visione del software come un insieme di oggetti cooperanti, piuttosto che un insieme di funzioni o semplicemente un elenco di istruzioni per il computer (come è nella visione tradizionale). In OOP, ogni oggetto è in grado di ricevere messaggi, elaborare dati, e inviare messaggi ad altri oggetti. Ogni oggetto può essere visto come una piccola macchina indipendente con ruolo o responsabilità distinti.

- -

OOP promuove una maggiore flessibilità e mantenibilità nella programmazione, ed è molto popolare in ingegneria del software su larga scala. Poiché OOP sottolinea con forza la modularità, il codice object-oriented è più semplice da sviluppare e più facile da capire in seguito. Il codice object-oriented promuove un'analisi, codifica, e comprensione di situazioni e procedure complesse più diretta che con metodi di programmazione a minor modularità.1

- -

Terminologia

- -
-
{{Glossary("Namespace")}}
-
Un contenitore che consente agli sviluppatori di includere tutte le funzionalità sotto un nome unico, specifico per l'applicazione.
-
{{Glossary("Class")}}
-
Definisce le caratteristiche dell'oggetto. Una classe è una definizione del modello, delle proprietà e dei metodi di un oggetto.
-
{{Glossary("Object")}}
-
Istanza di una classe.
-
{{Glossary("Property")}}
-
Una caratteristica di un oggetto, come un colore.
-
{{Glossary("Method")}}
-
Una capacità di un oggetto, come ad esempio cammina. È una procedura o funzione associata a una classe.
-
{{Glossary("Constructor")}}
-
Un metodo invocato nel momento in cui l'oggetto viene istanziato. Di solito ha lo stesso nome della classe che lo contiene.
-
{{Glossary("Inheritance")}}
-
Una classe può ereditare caratteristiche da un'altra classe.
-
{{Glossary("Encapsulation")}}
-
Una modalità di raggruppamento di dati e metodi che ne fanno uso.
-
{{Glossary("Abstraction")}}
-
L'insieme del complesso di eredità, metodi e proprietà di un oggetto deve rispecchiare adeguatamente un modello reale.
-
{{Glossary("Polymorphism")}}
-
Poly significa "molti" e morfismo significa "forme". Classi diverse potrebbero definire lo stesso metodo o proprietà.
-
- - - -

Per una descrizione più ampia della programmazione orientata agli oggetti, vedi {{interwiki("wikipedia", "Object-oriented programming")}} su Wikipedia.

- - - -

Programmazione  prototype-based

- -

La programmazione prototype-based (basata sul prototipo) è un modello OOP che non utilizza le classi, ma piuttosto prima completa il comportamento di qualsiasi classe e poi riutilizza (equivalente all'ereditarietà nei linguaggi basati su classi) arricchendo (o sviluppando) oggetti prototipo esistenti. (Chiamata anche senza classi (classless), orientata al prototipo (prototype-oriented), o programmazione basata su istanza (instance-based).)

- -

L'esempio originale (e più canonico) di un linguaggio basato sui prototipi è {{interwiki("wikipedia", "Self (programming language)", "Self")}} sviluppato da David Ungar e Randall Smith. Tuttavia lo stile di programmazione senza classi diventa sempre più popolare negli ultimi tempi, ed è stato adottato per i linguaggi di programmazione come JavaScript, Cecil, NewtonScript, Io, MOO, REBOL, Kevo, Squeak (quando si utilizza il framework Viewer per manipolare componenti Morphic), e molti altri.1

- -

Programmazione  Object Oriented in JavaScript

- -

Namespace

- -

Un namespace è un contenitore che consente agli sviluppatori di includere tutte le funzionalità sotto un nome unico, specifico per l'applicazione. In JavaScript un namespace è solo un altro oggetto che contiene metodi, proprietà e oggetti.

- -
-

Nota: È importante notare che in JavaScript non c'è alcuna differenza a livello di linguaggio tra oggetti regolari e namespace. Questo differenzia da molti altri linguaggi orientati agli oggetti e può essere fonte di confusione per i nuovi programmatori JavaScript.

-
- -

L'idea alla base della creazione di un namespace in JavaScript è semplice: creare un oggetto globale, e tutte le variabili, i metodi e le funzioni diventano proprietà di tale oggetto. L'uso dei namespace riduce anche il rischio di conflitti tra nomi in un'applicazione, poiché gli oggetti di ciascuna applicazione sono proprietà di un oggetto globale definito dall'applicazione.

- -

Creiamo un oggetto globale chiamato MYAPP:

- -
// global namespace
-var MYAPP = MYAPP || {};
- -

Nel codice di esempio di sopra prima viene testato se MYAPP è già definito (sia nello stesso o in un altro file). Se sì, allora viene utilizzato l'oggetto globale MYAPP già esistente, altrimenti viene creato un oggetto vuoto chiamato MYAPP che incapsula metodi, funzioni, variabili e oggetti.

- -

Possaimo anche creare sotto-namespace (tieni presente che l'oggetto globale deve essere definito prima):

- -
// sub namespace
-MYAPP.event = {};
- -

La seguente è la sintassi del codice per la creazione di un namespace e l'aggiunta di variabili, funzioni, e un metodo:

- -
// Create container called MYAPP.commonMethod for common method and properties
-MYAPP.commonMethod = {
-  regExForName: "", // define regex for name validation
-  regExForPhone: "", // define regex for phone no validation
-  validateName: function(name){
-    // Do something with name, you can access regExForName variable
-    // using "this.regExForName"
-  },
-
-  validatePhoneNo: function(phoneNo){
-    // do something with phone number
-  }
-}
-
-// Object together with the method declarations
-MYAPP.event = {
-    addListener: function(el, type, fn) {
-    // code stuff
-    },
-    removeListener: function(el, type, fn) {
-    // code stuff
-    },
-    getEvent: function(e) {
-    // code stuff
-    }
-
-    // Can add another method and properties
-}
-
-// Syntax for Using addListener method:
-MYAPP.event.addListener("yourel", "type", callback);
- -

Oggetti incorporati (built-in) standard

- -

JavaScript ha diversi oggetti inclusi nel suo nucleo, per esempio ci sono oggetti come Math, Object, Array e String. L'esempio seguente mostra come utilizzare l'oggetto Math per ottenere un numero casuale utilizzando il suo metodo random() .

- -
console.log(Math.random());
- -
Nota: Questo e tutti gli ulteriori esempi presuppongono che una funzione chiamata {{domxref("console.log()")}} sia definita a livello globale. La funzione console.log() in realtà non è parte di JavaScript in sé, ma molti browser la implementano per aiutare il debug.
- -

Vedi JavaScript Reference: Standard built-in objects for una lista degli oggetti di nucleo in JavaScript.

- -

Ogni oggetto in JavaScript è una instanza dell'oggetto Object e perciò ne eredita tutte le sue  proprietà e metodi.

- -

Oggetti utente

- -

La classe

- -

JavaScript è un linguaggio basato sui prototipi e non contiene alcuna dichiarazione di classe, come invece si trova in C ++ o Java. Questo a volte è fonte di confusione per i programmatori abituati ai linguaggi con una dichiarazione class. JavaScript utilizza le funzioni come costruttori per le classi. Definire una classe è facile come definire una funzione. Nell'esempio sottostante si definisce una nuova classe chiamata Person con un costruttore vuoto.

- -
var Person = function () {};
- -

L'oggetto (istanza di classe)

- -

Per creare una nuova istanza di un oggetto obj utilizziamo l'istruzione new obj assegnando il risultato (che è di tipo obj) ad una variabile, per poi accedervi successivamente.

- -

Nell'esempio precedente abbiamo definito una classe chiamata  Person. In quello seguente creiamo due istanze (person1 e person2).

- -
var person1 = new Person();
-var person2 = new Person();
- -
Nota: Prego vedi {{jsxref("Object.create()")}} per un ulteriore nuovo metodo d'istanza che crea una istanza non inizializzata.
- -

Il costruttore

- -

Il costruttore viene chiamato quando si instanzia un oggetto (il momento in cui si crea l'istanza dell'oggetto). Il costruttore è un metodo della classe. In JavaScript la funzione funge da costruttore dell'oggetto, pertanto non è necessario definire esplicitamente un metodo costruttore. Ogni azione dichiarata nella classe viene eseguita al momento della creazione di un'istanza.

- -

Il costruttore viene utilizzato per impostare le proprietà dell'oggetto o per chiamare i metodi che preparano l'oggetto per il suo uso. L'aggiunta di metodi di classe e le loro definizioni si effettua utilizzando una sintassi diversa descritta più avanti in questo articolo.

- -

Nell'esempio seguente il costruttore della classe Person registra un messaggio quando viene istanziato un oggetto Person.

- -
var Person = function () {
-  console.log('instance created');
-};
-
-var person1 = new Person();
-var person2 = new Person();
- -

La proprietà (attributo di oggetto)

- -

Le proprietà sono variabili contenute nella classe; ogni istanza dell'oggetto ha queste proprietà. Le proprietà sono impostate nel costruttore (funzione) della classe in modo che siano creati su ogni istanza.

- -

La parola chiave this, che si riferisce all'oggetto corrente, consente di lavorare con le proprietà all'interno della classe. L'accesso (in lettura o scrittura) ad una proprietà al di fuori della classe è fatto con la sintassi: NomeIstanza.Proprietà, proprio come in C ++, Java, e molti altri linguaggi. (All'interno della classe la sintassi this.Proprietà è utilizzata per ottenere o impostare il valore della proprietà.)

- -

Nell'esempio seguente, definiamo al momento della creazione  la proprietà firstName per la classe Person:

- -
var Person = function (firstName) {
-  this.firstName = firstName;
-  console.log('Person instantiated');
-};
-
-var person1 = new Person('Alice');
-var person2 = new Person('Bob');
-
-// Show the firstName properties of the objects
-console.log('person1 is ' + person1.firstName); // logs "person1 is Alice"
-console.log('person2 is ' + person2.firstName); // logs "person2 is Bob"
- -

I metodi

- -

I metodi sono funzioni (e definiti come funzioni), ma per il resto seguono la stessa logica delle proprietà. Chiamare un metodo è simile all'accesso a una proprietà, ma si aggiunge () alla fine del nome del metodo, eventualmente con argomenti. Per definire un metodo va assegnata una funzione a una proprietà della proprietà prototype della classe. In seguito sarà possibile chiamare il metodo sull'oggetto utilizzando lo stesso nome assegnato alla funzione.

- -

Nell'esempio seguente definiamo e usiamo il metodo sayHello() per la classe Person.

- -
var Person = function (firstName) {
-  this.firstName = firstName;
-};
-
-Person.prototype.sayHello = function() {
-  console.log("Hello, I'm " + this.firstName);
-};
-
-var person1 = new Person("Alice");
-var person2 = new Person("Bob");
-
-// call the Person sayHello method.
-person1.sayHello(); // logs "Hello, I'm Alice"
-person2.sayHello(); // logs "Hello, I'm Bob"
- -

In JavaScript i metodi sono oggetti funzione regolarmente associati a un oggetto come una proprietà, il che significa che è possibile richiamare i metodi "fuori dal contesto". Si consideri il seguente codice di esempio:

- -
var Person = function (firstName) {
-  this.firstName = firstName;
-};
-
-Person.prototype.sayHello = function() {
-  console.log("Hello, I'm " + this.firstName);
-};
-
-var person1 = new Person("Alice");
-var person2 = new Person("Bob");
-var helloFunction = person1.sayHello;
-
-// logs "Hello, I'm Alice"
-person1.sayHello();
-
-// logs "Hello, I'm Bob"
-person2.sayHello();
-
-// logs "Hello, I'm undefined" (or fails
-// with a TypeError in strict mode)
-helloFunction();
-
-// logs true
-console.log(helloFunction === person1.sayHello);
-
-// logs true
-console.log(helloFunction === Person.prototype.sayHello);
-
-// logs "Hello, I'm Alice"
-helloFunction.call(person1);
- -

Come dimostra questo esempio tutti i riferimenti alla funzione sayHello — quello su  person1, su Person.prototype, nella variabile helloFunction, ecc.— si riferiscono tutti alla stessa funzione. Il valore di this nel corso di una chiamata alla funzione dipende da come noi lo chiamiamo. Più comunemente, quando chiamiamo this  in un'espressione dove abbiamo ottenuto la funzione da una proprietà di oggetto — person1.sayHello()this è riferito all'oggetto da cui abbiamo ottenuto la funzione (person1), questa è la ragione per cui person1.sayHello() usa il  nome "Alice" e person2.sayHello() usa il nome "Bob".  Ma se lo chiamiamo in altri modi, this è impostato in modo diverso: chiamare this da una variabile— helloFunction()imposta this come riferimento all'oggetto globale (window, sui browser). Dal momento che l'oggetto globale (probabilmente) non dispone di una proprietà firstName otteniamo "Hello, I'm undefined". (Questo accade in modalità blanda (loose mode); sarebbe stato diverso [un errore] in strict mode, ma per evitare confusione qui non entreremo nei dettagli). Oppure si può impostare  this esplicitamente utilizzando Function#call (o Function#apply), come illustrato alla fine dell'esempio.

- -
Nota: Vedi approfondimenti su this in Function#call e Function#apply
- -

Eredità

- -

L'ereditarietà è un modo per creare una classe come una versione specializzata di una o più classi (JavaScript supporta solo l'ereditarietà singola). La classe specializzata viene comunemente chiamata figlio, e l'altra classe viene comunemente chiamato padre. In JavaScript si esegue questa operazione assegnando un'istanza della classe padre alla classe figlio, e poi specializzandola. Nel browser moderni è anche possibile utilizzare Object.create per implementare l'ereditarietà.

- -
-

Nota: JavaScript non rileva  prototype.constructor della classe figlio (vedi Object.prototype), quindi devi farlo manualmente. Vedi la domanda "Why is it necessary to set the prototype constructor?" su Stackoverflow.

-
- -

Nell'esempio seguente definiamo la classe  Student come classe figlio di Person. Quindi ridefiniamo il metodo sayHello() e aggiungiamo il metodo sayGoodBye() .

- -
// Define the Person constructor
-var Person = function(firstName) {
-  this.firstName = firstName;
-};
-
-// Add a couple of methods to Person.prototype
-Person.prototype.walk = function(){
-  console.log("I am walking!");
-};
-
-Person.prototype.sayHello = function(){
-  console.log("Hello, I'm " + this.firstName);
-};
-
-// Define the Student constructor
-function Student(firstName, subject) {
-  // Call the parent constructor, making sure (using Function#call)
-  // that "this" is set correctly during the call
-  Person.call(this, firstName);
-
-  // Initialize our Student-specific properties
-  this.subject = subject;
-};
-
-// Create a Student.prototype object that inherits from Person.prototype.
-// Note: A common error here is to use "new Person()" to create the
-// Student.prototype. That's incorrect for several reasons, not least 
-// that we don't have anything to give Person for the "firstName" 
-// argument. The correct place to call Person is above, where we call 
-// it from Student.
-Student.prototype = Object.create(Person.prototype); // See note below
-
-// Set the "constructor" property to refer to Student
-Student.prototype.constructor = Student;
-
-// Replace the "sayHello" method
-Student.prototype.sayHello = function(){
-  console.log("Hello, I'm " + this.firstName + ". I'm studying "
-              + this.subject + ".");
-};
-
-// Add a "sayGoodBye" method
-Student.prototype.sayGoodBye = function(){
-  console.log("Goodbye!");
-};
-
-// Example usage:
-var student1 = new Student("Janet", "Applied Physics");
-student1.sayHello();   // "Hello, I'm Janet. I'm studying Applied Physics."
-student1.walk();       // "I am walking!"
-student1.sayGoodBye(); // "Goodbye!"
-
-// Check that instanceof works correctly
-console.log(student1 instanceof Person);  // true 
-console.log(student1 instanceof Student); // true
- -

Per quanto riguarda la linea Student.prototype = Object.create(Person.prototype); : in vecchi interpreti JavaScript senza  Object.create, si può utilizzare un "polyfill" (anche detto "shim", vedi l'articolo collegato), oppure utilizzare una funzione che produce il medesimo risultato, come:

- -
function createObject(proto) {
-    function ctor() { }
-    ctor.prototype = proto;
-    return new ctor();
-}
-
-// Usage:
-Student.prototype = createObject(Person.prototype);
- -
Nota: Vedi Object.create per maggiori informazioni su ciò che fa uno shim per vecchi interpreti.
- -

Essere sicuri che  this punti alla cosa giusta a prescindere da come l'oggetto sia istanziato può essere difficile. Tuttavia c'e una tecnica semplice per renderlo più facile.

- -
var Person = function(firstName) {
-  if (this instanceof Person) {
-    this.firstName = firstName;
-  } else {
-    return new Person(firstName);
-  }
-}
- -

Incapsulamento

- -

Nell'esempio precedente Student non ha bisogno di sapere come sia realizzato il metodo walk() della classe Person, ma può comunque utilizzarlo; la classe Student non ha bisogno di definire in modo esplicito questo metodo se non vogliamo cambiarlo. Questo è chiamato incapsulamento, per cui ogni classe impacchetta dati e metodi in una singola unità.

- -

Il nascondere informazioni (information hiding) è una caratteristica comune ad altre linguaggi, spesso in forma di  metodi / proprietà private e protette. Anche se si potrebbe simulare qualcosa di simile in JavaScript, questo non è un requisito per fare programmazione Object Oriented.2

- -

Astrazione

- -

L'astrazione è un meccanismo che permette di modellare la parte corrente del problema, sia con eredità (specializzazione) o la composizione. JavaScript ottiene la specializzazione per eredità, e la composizione permettendo che istanze di classe siano valori di attributi di altri oggetti.

- -

La classe Function di Javascript eredita dalla classe Object (questo dimostra la specializzazione del modello) e la proprietà Function.prototype è un'istanza di oggetto (ciò dimostra la composizione).

- -

The JavaScript Function class inherits from the Object class (this demonstrates specialization of the model) and the Function.prototype property is an instance of Object (this demonstrates composition).

- -
var foo = function () {};
-
-// logs "foo is a Function: true"
-console.log('foo is a Function: ' + (foo instanceof Function));
-
-// logs "foo.prototype is an Object: true"
-console.log('foo.prototype is an Object: ' + (foo.prototype instanceof Object));
- -

Polimorfismo

- -

Così come tutti i metodi e le proprietà sono definite all'interno della proprietà prototype, classi diverse possono definire metodi con lo stesso nome; i metodi sono nell'ambito della classe in cui sono definiti, a meno che le due classi siano in un rapporto padre-figlio (cioè una eredita dall'altra in una catena di ereditarietà).

- - - -

Note

- -

Le tecniche presentate in questo articolo per attuare la programmazione orientata agli oggetti non sono le uniche che possono essere utilizzate in JavaScript, che è molto flessibile in termini di come la programmazione orientata agli oggetti possa essere eseguita.

- -

Allo stesso modo, le tecniche qui indicate non usano alcuna violazione di linguaggio, né imitano implementazioni di teorie di oggetti di altri linguaggi.

- -

Ci sono altre tecniche che rendono la programmazione orientata agli oggetti in JavaScript ancora più avanzata, ma sono oltre la portata di questo articolo introduttivo.

- -

Riferimenti

- -
    -
  1. {{ Ref() }} Mozilla. "Core JavaScript 1.5 Guide", http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide
  2. -
  3. {{ Ref() }} wikipedia. "Object-oriented programming", http://en.wikipedia.org/wiki/Object-...ed_programming
  4. -
- -
-

Original Document Information

- - -
- -

{{ languages( { "es": "es/Introducción_a_JavaScript_orientado_a_objetos"} ) }}

diff --git a/files/it/web/javascript/javascript_technologies_overview/index.html b/files/it/web/javascript/javascript_technologies_overview/index.html new file mode 100644 index 0000000000..9f2b0fbb56 --- /dev/null +++ b/files/it/web/javascript/javascript_technologies_overview/index.html @@ -0,0 +1,81 @@ +--- +title: Il DOM e JavaScript +slug: Web/JavaScript/Il_DOM_e_JavaScript +tags: + - DOM + - JavaScript + - Tutte_le_categorie +translation_of: Web/JavaScript/JavaScript_technologies_overview +--- +

Il Grande Disegno

+ +

Gli effetti visivi come muovere i layer sulla pagina, mostrare e nascondere layer, far comparire menu, eccetera, sono spesso indicati come "DHTML", o "Dynamic HTML". Alcuni hanno dubbi sull'effettiva utilità di queste tecnologie in pagine web che dovrebbero trasmettere del contenuto e non la presentazione, ma dobbiamo comunque prendere atto della loro larga diffusione.

+ +

Molti web master si limitano ad andare sui siti che offrono script DHTML e ricopiare il codice nelle loro pagine, senza interessarsi a come funzionano quegli script DHTML. Sfortunatamente la maggior parte di questi siti parlano di "javascript" e "DHTML", ma mai di DOM, il quale, sebbene sia un concetto introdotto da parecchio, solo di recente sta entrando nel gergo del web designer medio.

+ +

E' una grande sfida per un progetto come Mozilla convincere i possessori di questi siti che ***it is worth coding for the W3C DOM, which sometimes means a lot of work, and drops support for the older browsers. It is also a big challenge to get the facts straight concerning the support for the W3C DOM. *** Uno dei più grandi problemi che incontrano alcuni web developer è la confusione tra JavaScript, DHTML e il DOM. In questo articolo tenteremo di chiarire le cose, e di spiegare le relazioni fra queste utili ed elaborate tecnologie.

+ +

JavaScript, IL Linguaggio di Web Scripting

+ +

JavaScript è un "linguaggio di scripting di oggetti" sviluppato inizialmente alla Netscape Communications Corp. da Brendan Eich, che oggi è uno dei leader del progetto Mozilla. Il motore JavaScript usato da Mozilla si chiama SpiderMonkey, e aderisce alla specifica ECMA-262 3°revisione(di cui è un superset; guarda anche la pagina ECMAScript).

+ +

Contrariamente a diffuse errate credenze, JavaScript non è "Java Interpretato". Possiamo dire che JavaScript è un linguaggio di scripting dinamico che supporta la costruzione di oggetti basata su prototipi. La sintassi di base è volutamente simile sia a Java che a C++ per ridurre il numero di nuovi concetti richiesti per imparare il linguaggio. Il grande vantaggio di JavaScript è che è estremamente facile da imparare se vuoi fare programmazione di base (come quella richiesta per semplici DHTML). Niente tipi di variabili a vista, stringhe semplici da usare, neutralità totale della piattaforma,ecc. Per i programmatori avanzati può essere usato sia come linguaggio orientato agli oggetti che come linguaggio procedurale.

+ +

Gran parte di questo paragrafo su JavaScript è stato preso dalla pagina JavaScript di Mozilla. Puoi anche consultare la più recente specifica ECMA.

+ +

Il Modello a Oggetti del Documento, un insieme di interfacce indipendenti dal linguaggio

+ +

Mentre Javascript è il linguaggio di programmazione che ti permette di operare sugli oggetti DOM, il DOM ti fornisce metodi e proprietà per recuperare, modificare, aggiornare ed eliminare parti del documento su cui stai lavorando. Per esempio, potresti recuperare il valore di un campo di testo e metterlo in una variabile stringa con il DOM; a questo punto puoi usare l'operatore Javascript di concatenazione + , per unire quella stringa ad un'altra, in base a ciò che vuoi ottenere. Potresti quindi usare il metodo alert() per mostrare la stringa all'utente attraverso una finestra di dialogo. Guarda anche gli altri esempi più sotto.

+ +

In che senso "indipendente dal linguaggio"? Non è javascript l'unico modo per accedere al DOM? No, ad esempio Mozilla usa il DOM sia col C++ che col Javascript per la sua interfaccia utente. Questi sono alcuni dei linguaggi che hanno un'implementazione del DOM: Perl, Java, ActiveX, Python; ciò è possibile grazie all'indipendenza del DOM dal linguaggio di programmazione.

+ +

Il DOM e Javascript - Chi sta facendo cosa?

+ +

Arriviamo al punto principale di questo documento: chi sta facendo cosa? In uno script che ho inserito nella mia pagina, dov'è il DOM, e dov'è Javascript? Guardiamo da vicino un piccolo esempio: il codice prende tutti i tag <a> della pagina e li mette in una NodeList che abbiamo chiamato "anchorTags". Quindi per ogni tag ancora facciamo comparire un avviso contenente il valore dell'attributo href del tag. In blu c'è Javascript, in rosso il DOM.

+ +
var anchorTags = document.getElementsByTagName("a");
+for (var i = 0; i < anchorTags.length ; i++)
+{
+   alert("Href of " + i + "-th element is : " + anchorTags[i].href + "\n");
+}
+
+ +

Spiegazione

+ +

Questo frammento di codice mostra cos'è Javascript, e cos'è DOM..

+ +
+
var anchorTags =
+
Crea una variabile chiamata "anchorTags".
+
document.getElementsByTagName("a")
+
L'interfaccia Document è la prima interfaccia definita nel DOM1 Core, e document è l'oggetto che implementa l'interfaccia Document. L'oggetto document contiene tutto ciò che c'è nella pagina.
+ Il DOM1 Core definisce il metodo getElementsByTagName() Nell'interfaccia Document. Questo metodo mette in una NodeList(una sorta di array specifico per contenere i nodi del DOM)tutti i tag il cui nome corrisponde al parametro passato alla funzione, in ordine di apparizione nel codice sorgente del documento. La variabile anchorTags è quindi ora una NodeList.
+
;
+
Il punto e virgola che chiude le istruzioni. Roba di Javascript.
+
for (var i = 0; i <
+
Tipico ciclo "for" in un linguaggio di programmazione. Ci consente di scorrere tutti i nodi contenuto nella NodeList salvata in anchorTags. "i" è una variabile temporanea di Javascript.
+
anchorTags.length
+
Nel DOM1 Core è definita la proprietà length dell'interfaccia NodeList. Restituisce un intero che è il numero di nodi contenuti nella NodeList.
+
; i++) {
+
Tipica istruzione per incrementare di 1 una variabile. Javascript.
+
alert(
+
alert() è un metodo del DOM che apre una finestrella in mezzo allo schermo con dentro la stringa che gli hai passato. Nota: questo metodo fa parte di ciò che viene chiamato DOM level 0, o DOM0; è un insieme di interfacce che non fanno parte di nessuna specifica DOM, ma sono comunque implementate da alcuni browser.
+
"Href of this a element is : " +
+
Una stringa letterale e un operatore di concatenazione di stringhe. JavaScript.
+
anchorTags{{ mediawiki.external('i') }}.href
+
"href" è una proprietà definita dall'intefaccia HTMLAnchorElement della specifica DOM1 HTML. Restituisce il valore dell'attributo href dell'elemento ancora, se presente.
+ Usiamo anche anchorTags{{ mediawiki.external('i') }}, la stessa sintassi usata in Javascript per accedere all'i-esimo elemento di un array. Un modo più "linguaggio-indipendente" per accedere a un elemento di una NodeList è l'uso del metodo item(), definito nella interfaccia NodeList: anchorTags.item(1).href, ma la maggior parte delle implementazioni Javascript permettono di usare la più sbrigativa sintassi per array, che è ciò che la maggior parte dei programmatori usano.
+
+ "\n");
+
Un'altra concatenazione di stringhe. Inserisce un ritorno del carrello alla fine della stringa.
+
}
+
Fine del ciclo "for".
+
+ +
+

Original Document Information

+ + +
diff --git a/files/it/web/javascript/memory_management/index.html b/files/it/web/javascript/memory_management/index.html new file mode 100644 index 0000000000..d1cd6c4dca --- /dev/null +++ b/files/it/web/javascript/memory_management/index.html @@ -0,0 +1,197 @@ +--- +title: Gestione della memoria +slug: Web/JavaScript/Gestione_della_Memoria +translation_of: Web/JavaScript/Memory_Management +--- +
{{JsSidebar("Advanced")}}
+ +

Introduzione

+ +

Alcuni linguaggi di programmazione, come ad esempio C e C++, possiedono funzioni per la gestione della memoria a basso livello come malloc() e free(); in JavaScript l'allocazione e la de-allocazione della memoria (oggetti, stringhe, ecc.) avviene "automaticamente" grazie alla presenza del Garbage Collection. Il termine "automaticamente" è spesso fonte di confusione tra i programmatori JavaScript (e di altri linguaggi ad alto livello) poichè da l'impressione che si possa non preoccuparsi riguardo la gestione della memoria. Questo è un errore!

+ +

Ciclo di vita della memoria

+ +

A prescindere dal linguaggio di programmazione, il ciclo di vita della memoria è pressappoco sempre lo stesso:

+ +
    +
  1. Allocazione della memoria necessaria
  2. +
  3. Utilizzo della memoria (scrittura, lettura)
  4. +
  5. Rilascio della memoria allocata quando non è più necessaria
  6. +
+ +

I primi due punti sono espliciti in tutti i linguaggi; l'ultimo invece è esplicito nei linguaggi a basso livello, mentre il più delle volte implicito nei linguaggi ad alto livello come JavaScript.

+ +

Allocazione in JavaScript

+ +

Inizializzazione con valore

+ +

Per evitare che il programmatore debba allocare ogni variabile utilizzata, JavaScript lo fa contestualmente alla dichiarazione:

+ +
var n = 123; // alloca memoria per un numero
+var s = "qwerty"; // alloca memoria per una stringa
+
+var o = {
+  a: 1,
+  b: null
+}; // alloca memoria per un oggetto e i valori contenuti
+
+// (come un oggetto) alloca memoria per l'array e i valori contenuti
+var a = [1, null, "abra"];
+
+function f(a){
+  return a + 2;
+} // alloca una funzione (cioè un oggetto invocabile)
+
+// istruzioni più complesse anche allocano un oggetto
+someElement.addEventListener('click', function(){
+  someElement.style.backgroundColor = 'blue';
+}, false);
+
+ +

Allocazione via chiamata di funzione

+ +

La chiamata di alcune funzioni risultano nell'allocazione di un oggetto, come nel seguente esempio:

+ +
var d = new Date();
+// alloca un DOM element
+var e = document.createElement('div');
+
+ +

Alcuni metodi allocano nuovi valori od oggetti:

+ +
var s = "qwerty";
+var s2 = s.substr(0, 3); // s2 è una nuova stringa
+// Dato che le stringhe sono valori immutabili,
+// JavaScript può decidere di non allocare memoria per una nuova stringa,
+// ma semplicemente di salvare il range [0, 3].
+
+var a = ["ouais ouais", "nan nan"];
+var a2 = ["generation", "nan nan"];
+var a3 = a.concat(a2);
+// Un nuovo array di 4 elementi, la concatenazione degli elementi di a e a2
+
+ +

Utilizzo dei valori

+ +

Usare i valori in sostanza significa accedere alla memoria allocata. Questo può essere fatto leggendo o scrivendo il valore di una variabile, di una proprietà di un oggetto, o anche semplicemente passando un argomento a una funzione.

+ +

Rilascio della memoria quando non più necessaria

+ +

La maggior parte dei problemi riguardo la gestione della memoria arrivano in questa fase; L'impresa più difficile è determinare quando "la memoria allocata non è più necessaria". Ciò si traduce per il programmatore in individuare dove, nel codice, questo pezzo di memoria non risulta più necessario, e quindi liberarlo.

+ +

I linguaggi ad alto livello hanno una funzionalità chiamata "Garbage Collector" il cui compito è di seguire l'allocazione e l'uso della memoria così da determinare quando una porzione della memoria allocata non è più necessaria e liberarla automaticamente. Questo processo è un approssimazione dato che il problema generico di conoscere se una porzione di memoria serve o no è irrisolvibile (non può essere risolto da un algoritmo).

+ +

Garbage Collection

+ +

Partendo dal presupposto che il generico problema di sapere dove una determinata porzione di memoria "non serve più" è irrisolvibile, come conseguenza, l'implementazione dei garbege collection sono una restrizione della soluzione del problema generico. Questa sezione illustra le nozioni necessarie a capire il funzionamento dei principali algoritmi che implementano i garbage collection e le loro limitazioni.

+ +

Referenze

+ +

L'idea principale su cui si basano gli algoritmi di garbage collection sono le referenze. Nel contesto della gestione della memoria, un oggetto è referente di un altro se può accedere a quest'ultimo (sia in modo implicito che esplicito). Ad esempio, un oggetto JavaScript è referente del suo prototype (referenza implicita) e ai valori delle sue proprietà (referenza esplicita).

+ +

In questo contesto, il concetto di "oggetto" si estende a qualcosa di molto più ampio rispetto al tradizionale concetto di "oggetto JavaScript" e contiene function scopes (or the global lexical scope).

+ +

Reference-counting garbage collection

+ +

Quello qui descritto è l'algoritmo di garbage collection più semplice. Esso riduce il problema da "quando un oggetto non serve più" a "quando un oggetto non è più referenziato da nessun altro oggetto". Un oggetto è considerato garbage collectable (letteralmente, spazzatura da raccogliere) se nessun altro oggetto ha almeno una referenza ad esso.

+ +

Esempio

+ +
var o = {
+  a: {
+    b:2
+  }
+};
+// Alloca 2 oggetti. Il primo è referenziato dall'altro come sua proprietà.
+// L'altro è referenziato dalla dalla virtù di essere assegnato alla variabile 'o'.
+// Ovviamente, nessuno dei due può essere cancellato per liberare memoria
+
+
+var o2 = o; // la variabile 'o2' è il secondo oggetto
+            // che referenzia lo stesso oggetto di 'o'
+o = 1;      // ora l'oggetto che originariamente era in 'o' ha un'unica referenza
+            // rappresentata dalla variabile 'o2'
+
+var oa = o2.a; // referenza alla proprietà 'a' dell'oggetto.
+               // Quest'oggetto ora ha 2 referenze: una come proprietà di 'o2'
+               // e una come variabile 'oa'
+
+o2 = "yo"; // L'oggetto che originariamente era in 'o' adesso non
+           // più alcuna referenza e può essere cancellato.
+           // Però la sua proprietà 'a' è ancora referenziata
+           // dall'oggetto 'oa', quindi non può essere ancora eliminato
+
+oa = null; // la proprietà 'a' del precedente oggetto adesso non ha
+           // alcuna referenza. Può essere cancellata.
+
+ +

Limitazione: cicli di referenze

+ +

Questo algotitmo ha una limitazione quando entra in un ciclo di referenze. Nell'esempio seguente sono creati due oggetti che si referenziano a vicenda, uno referenzia l'altro e viceversa, creando un ciclo di referenze (dipendenza ciclica). In questo modo ogni oggetto ha almento una referenza, l'algoritmo del reference-countig (ovvero quello che "conta" quante referenze ha un oggetto) da come risultato che nessuno dei due oggetti può essere cancellato (non sono garbage-collactable).

+ +
function f(){
+  var o = {};
+  var o2 = {};
+  o.a = o2; // o referenzia o2
+  o2.a = o; // o2 referenzia o
+
+  return "qwerty";
+}
+
+f();
+// Two objects are created and reference one another thus creating a cycle.
+// They will not get out of the function scope after the function call, so they
+// are effectively useless and could be free'd.
+// However, the reference-counting algorithm considers that since each of both
+// object is referenced at least once, none can be garbage-collected.
+
+ +

Esempio reale

+ +

Internet Explorer 6 e 7 sono conosciuti per avere un reference-counting garbage collector per gli oggetti DOM. I cicli di referenze sono errori comuni che possono generare uno spreco di memoria (memory leaks).

+ +
var div;
+window.onload = function(){
+  div = document.getElementById("myDivElement");
+  div.circularReference = div;
+  div.lotsOfData = new Array(10000).join("*");
+};
+
+ +

Nell'esempio precedente, l'elemento "myDivElement" ha una referenza circolare con se stesso nella proprietà "circularReference". Se la proprietà non è esplicitamente rimossa o annullata, un reference-counting garbage collector avrà sempre almeno una referenza intatta che manterrà l'elemento in memoria anche se esso fosse rimosso dal DOM. Se un oggetto trattiene molta memoria e ha almeno una referenza (come illustrato nell'esempio precedente con la proprietà "lotsOfData") la memoria da esso occupata non sarà mai rilasciata.

+ +

L'algoritmo mark-and-sweep

+ +

Questo algoritmo è il più famoso degli algoritmi di tracing; la tecnica del tracing è concettualmente molto semplice e si basa sulla definizione "quando un oggetto diventa irraggiungibile".

+ +

Essa consiste nel prendere come riferimento gli oggetti root (indice dell'albero) e, partendo da essi, mediante una ricorsione, marcare (tramite un bit o una mappa distinta) tutti gli oggetti collegati tra loro da un riferimento. Al termine di questa operazione, gli oggetti raggiungibili saranno marcati mentre quelli non raggiungibili saranno eliminati.

+ +

L'algoritmo mark-and-sweep (marca e butta via) si suddivide in due fasi: la prima fase (mark) nella quale l'algoritmo marca tutti gli oggetti che hanno almeno un riferimento attivo; nella seconda fase (sweep) nella quale tutti gli oggetti non marcati vengono liberati e la memoria viene restituita.

+ +

A differenza della tecnica del reference counting il cui il costo dell'algoritmo è proporzionale all'ammontare del lavoro eseguito dal programma (ogni volta che si alloca/dealloca un oggetto bisogna creare-incrementare/decrementare il contatore), la tecnica del tracing è proporzionale alla dimensione della memoria ed è sicuramente più efficiente.

+ +

I cicli non sono più un problema

+ +

Nel primo esempio, dopo che la funzione ha restituito un risultato, i 2 oggetti non sono più referenziati da nessun altro oggetto raggiungibile dall'oggetto globale (root). Ne consegue che saranno irraggiungibili dal garbage collector e quindi eleminati.

+ +

La stessa cosa accade con il secondo esempio. Una volta che il div e la sua variabile sono diventati irraggiungibili dalle radici, essi possono essere cancellati nonostante abbiano una referenza ciascuno.

+ +

Limitazione: gli oggetti devono essere esplicitamente irragiungibili

+ +

Sebbene sia marcata come una limitazione, è raramente raggiunta in pratica ed è anche il motivo per cui nessuno si preoccupa, di solito, dei garbage collector.

+ +
+

Piccolo appunto italiano

+ +

Tutte le parole tagliate sono state tradotte letteralmente ma in modo che la frase non perda di significato.

+ +

cit. Il traduttore

+
+ +

See also

+ + diff --git a/files/it/web/javascript/reference/classes/constructor/index.html b/files/it/web/javascript/reference/classes/constructor/index.html new file mode 100644 index 0000000000..afc6c44526 --- /dev/null +++ b/files/it/web/javascript/reference/classes/constructor/index.html @@ -0,0 +1,161 @@ +--- +title: costruttore +slug: Web/JavaScript/Reference/Classes/costruttore +translation_of: Web/JavaScript/Reference/Classes/constructor +--- +
{{jsSidebar("Classes")}}
+ +

Il metodo constructor è un metodo speciale usato per la creazione e l'inizializzazione di un oggetto creato da  una classe.

+ +

Sintassi

+ +
constructor([argomenti]) { ... }
+ +

Descrizione

+ +

In una classe ci può essere un solo metodo con il nome "constructor". Se una classe contiene una o più occorrenze del metodo constructor viene sollevato un errore di tipo {{jsxref("SyntaxError")}}. 

+ +

Un costruttore può usare la keyword super per chiamare il costruttore di una classe genitore.

+ +

Se non viene specificato un metodo constructor, verrà usato quello di default.

+ +

Esempi

+ +

Usare il metodo constructor

+ +

Questo pezzo di codice è stato preso da classes sample (live demo).

+ +
class Square extends Polygon {
+  constructor(length) {
+    // Chiama il costruttore della classe padre usando lo stesso valore length
+    // come altezza e come larghezza del Poligono
+    super(length, length);
+    // Nota: Nelle classi derivate, super() deve essere chiamato prima
+    // dell'utilizzo di 'this', altrimenti viene sollevato un reference error.
+    this.name = 'Square';
+  }
+
+  get area() {
+    return this.height * this.width;
+  }
+
+  set area(value) {
+    this.area = value;
+  }
+}
+ +

Costruttori predefinito

+ +

Se non viene specificato un metodo costruttore, verrà usato quello di default. Per le classi base il costruttore di default è:

+ +
constructor() {}
+
+ +

Per le classi derivate invece è:

+ +
constructor(...args) {
+  super(...args);
+}
+ +

Specifiche

+ + + + + + + + + + + + + + + + + + + +
SpecificaStatoCommento
{{SpecName('ES6', '#sec-static-semantics-constructormethod', 'Constructor Method')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-static-semantics-constructormethod', 'Constructor Method')}}{{Spec2('ESDraft')}} 
+ +

Compatibilità con i Browser

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificaChromeFirefox (Gecko)Internet ExplorerOperaSafari
Supporto Base{{CompatChrome(42.0)}}{{CompatGeckoDesktop(45)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
Costruttore predefinito{{CompatUnknown}}{{CompatGeckoDesktop(45)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificaAndroidAndroid WebviewFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome per Android
Supporto Base{{CompatNo}}{{CompatChrome(42.0)}}{{CompatGeckoMobile(45)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatChrome(42.0)}}
Costruttore predefinito{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile(45)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

Vedi anche

+ + diff --git a/files/it/web/javascript/reference/classes/costruttore/index.html b/files/it/web/javascript/reference/classes/costruttore/index.html deleted file mode 100644 index afc6c44526..0000000000 --- a/files/it/web/javascript/reference/classes/costruttore/index.html +++ /dev/null @@ -1,161 +0,0 @@ ---- -title: costruttore -slug: Web/JavaScript/Reference/Classes/costruttore -translation_of: Web/JavaScript/Reference/Classes/constructor ---- -
{{jsSidebar("Classes")}}
- -

Il metodo constructor è un metodo speciale usato per la creazione e l'inizializzazione di un oggetto creato da  una classe.

- -

Sintassi

- -
constructor([argomenti]) { ... }
- -

Descrizione

- -

In una classe ci può essere un solo metodo con il nome "constructor". Se una classe contiene una o più occorrenze del metodo constructor viene sollevato un errore di tipo {{jsxref("SyntaxError")}}. 

- -

Un costruttore può usare la keyword super per chiamare il costruttore di una classe genitore.

- -

Se non viene specificato un metodo constructor, verrà usato quello di default.

- -

Esempi

- -

Usare il metodo constructor

- -

Questo pezzo di codice è stato preso da classes sample (live demo).

- -
class Square extends Polygon {
-  constructor(length) {
-    // Chiama il costruttore della classe padre usando lo stesso valore length
-    // come altezza e come larghezza del Poligono
-    super(length, length);
-    // Nota: Nelle classi derivate, super() deve essere chiamato prima
-    // dell'utilizzo di 'this', altrimenti viene sollevato un reference error.
-    this.name = 'Square';
-  }
-
-  get area() {
-    return this.height * this.width;
-  }
-
-  set area(value) {
-    this.area = value;
-  }
-}
- -

Costruttori predefinito

- -

Se non viene specificato un metodo costruttore, verrà usato quello di default. Per le classi base il costruttore di default è:

- -
constructor() {}
-
- -

Per le classi derivate invece è:

- -
constructor(...args) {
-  super(...args);
-}
- -

Specifiche

- - - - - - - - - - - - - - - - - - - -
SpecificaStatoCommento
{{SpecName('ES6', '#sec-static-semantics-constructormethod', 'Constructor Method')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-static-semantics-constructormethod', 'Constructor Method')}}{{Spec2('ESDraft')}} 
- -

Compatibilità con i Browser

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificaChromeFirefox (Gecko)Internet ExplorerOperaSafari
Supporto Base{{CompatChrome(42.0)}}{{CompatGeckoDesktop(45)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
Costruttore predefinito{{CompatUnknown}}{{CompatGeckoDesktop(45)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificaAndroidAndroid WebviewFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome per Android
Supporto Base{{CompatNo}}{{CompatChrome(42.0)}}{{CompatGeckoMobile(45)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatChrome(42.0)}}
Costruttore predefinito{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile(45)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -

Vedi anche

- - diff --git a/files/it/web/javascript/reference/functions/arguments/index.html b/files/it/web/javascript/reference/functions/arguments/index.html new file mode 100644 index 0000000000..c277074bca --- /dev/null +++ b/files/it/web/javascript/reference/functions/arguments/index.html @@ -0,0 +1,224 @@ +--- +title: Oggetto 'arguments' +slug: Web/JavaScript/Reference/Functions_and_function_scope/arguments +translation_of: Web/JavaScript/Reference/Functions/arguments +--- +
+
{{jsSidebar("Functions")}}
+
+ +

L'oggetto arguments è un oggetto Array-like corrispondente agli argomenti passati in una funzione 

+ +

{{EmbedInteractiveExample("pages/js/functions-arguments.html")}}

+ + + +

Sintassi

+ +
arguments
+ +

Descrizione

+ +

L'oggetto arguments è una variabile locale disponibile in tutte le funzioni (non-arrow). Si può fare riferimento agli argomenti di una funzione, al suo interno, usando l'oggetto  arguments. Questo oggetto contiene un elemento per ogni argomento passato alla funzione, il primo elemento è indicizzato a 0. Per esempio, se a una funzione sono passati tre argomenti, ci si può riferire ad essi come segue:

+ +
arguments[0]
+arguments[1]
+arguments[2]
+
+ +

Gli argomenti possono anche essere settati:

+ +
arguments[1] = 'nuovo valore';
+
+ +

L'oggetto arguments non è un {{jsxref("Array")}}. E' simile a un  Array, ma non ha le proprietà dell'Array, eccetto length. Per esempio, non ha il metodo pop. Tuttavia può essere convertito in un vero Array:

+ +
var args = Array.prototype.slice.call(arguments);
+var args = [].slice.call(arguments);
+
+// ES2015
+const args = Array.from(arguments);
+
+ +
+

Usare slice su arguments impedisce le ottimizzazioni in alcuni motori JavaScript (per esempio V8 - più informazioni). Se ne avete bisogno, provate a costruire un nuovo array iterando sull'oggetto arguments, piuttosto. Un'alternativa potrebbe essere usare l'odiato costruttore Array come una funzione:

+ +
var args = (arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments));
+
+ +

Si può usare l'oggetto arguments se si chiama una funzione con più argomenti di quanti la funzione dichiari formalmente di accettare. Questa tecnica è utile per le funzioni cui possono essere passati un numero variabile di argomenti. Si usi arguments.length per determinare il numero di argomenti passati alla funzione, e quindi si processi ogni argomento usando l'oggetto arguments. Per determinare il numero di parametri presenti nella dichiarazione di una funzione, si usi la proprietà Function.length.

+ +

Usare typeof con Arguments

+ +

Il typeof di arguments ritorna 'object'. 

+ +
console.log(typeof arguments); // 'object' 
+ +

Il typeof di ogni signolo argomento può essere determinato con l'uso degli indici.

+ +
console.log(typeof arguments[0]); //this will return the typeof individual arguments.
+ +

Usare la sintassi Spread con Arguments

+ +

Come è possibile fare con qualsiasi oggetto Array-like, si può usare il metodo {{jsxref("Array.from()")}} o lo spread operator per convertire arguments in un vero Array:

+ +
var args = Array.from(arguments);
+var args = [...arguments];
+
+ +

Proprietà

+ +
+
arguments.callee
+
Riferimento alla funzione in esecuzione.
+
arguments.caller {{ Obsolete_inline() }}
+
Riferimento alla funzione che ha invocato la funzione in esecuzione.
+
arguments.length
+
Riferimento al numero di argomenti passati alla funzione.
+
arguments[@@iterator]
+
Ritorna un nuovo oggetto Array Iterator che contiene i valori per ogni indice in arguments.
+
+ +

Esempi

+ +

Definire una funzione che concatena divere stringhe 

+ +

Questo esempio definisce una funzione che concatena diverse stringhe. L'unico argomento formale per la funzione è una stringa che specifica il carattere di separazione per gli elementi da concatenare. La funzione si definisce come segue:

+ +
function myConcat(separator) {
+  var args = Array.prototype.slice.call(arguments, 1);
+  return args.join(separator);
+}
+ +

Si può passare un numero indefinito di argomenti a questa funzione, e lei creerà una lista inserendo ciascun argomento come item della lista. 

+ +
// returns "red, orange, blue"
+myConcat(', ', 'red', 'orange', 'blue');
+
+// returns "elephant; giraffe; lion; cheetah"
+myConcat('; ', 'elephant', 'giraffe', 'lion', 'cheetah');
+
+// returns "sage. basil. oregano. pepper. parsley"
+myConcat('. ', 'sage', 'basil', 'oregano', 'pepper', 'parsley');
+ +

Definire una funzione che crea liste HTML

+ +

Questo esempio definisce una funzione che crea una stringa contenente l'HTML di una lista. L'unico argomento formale della funzione è una  stringa che è "u" se la lista deve essere ordinata, e "o" se la lista deve essere ordinata (numerata). La funzione è definita come segue:

+ +
function list(type) {
+  var result = '<' + type + 'l><li>';
+  var args = Array.prototype.slice.call(arguments, 1);
+  result += args.join('</li><li>');
+  result += '</li></' + type + 'l>'; // end list
+
+  return result;
+}
+ +

Si può passare un numero indefinito di argomenti a questa funzione, e lei aggiungerà ogni argomento come un elemento della lista del tipo indicato. Per esempio:

+ +
var listHTML = list('u', 'One', 'Two', 'Three');
+
+/* listHTML is:
+
+"<ul><li>One</li><li>Two</li><li>Three</li></ul>"
+
+*/
+ +

Parametri rest, default, e destructured

+ +

L'oggetto arguments può essere usato insieme a parametri rest, default, e destructured.

+ +
function foo(...args) {
+  return args;
+}
+foo(1, 2, 3); // [1,2,3]
+
+ +

Sebbene la presenza di parametri restdefault, o destructured non altera il comportamento dell'oggetto arguments nel codice scritto in strict mode, c'è una sottile differenza tra modalità strict e non-strict.

+ +

Quando una funzione non-strict non contiene parametri restdefault, o destructured, allora i valori nell'oggetto arguments  tracciano il valore degli argomenti (e vice versa). Si guardi il codice qui sotto:

+ +
function func(a) {
+  arguments[0] = 99; // updating arguments[0] also updates a
+  console.log(a);
+}
+func(10); // 99
+
+ +

e

+ +
function func(a) {
+  a = 99; // updating a also updates arguments[0]
+  console.log(arguments[0]);
+}
+func(10); // 99
+
+ +

Quando una funzione non-strict contiene parametri restdefault, o destructured, allora i valori nell'oggetto arguments non tracciano il valore degli argomenti (e vice versa). Al contrario, riflettono gli argomenti forniti al momento dell'invocazione:

+ +
function func(a = 55) {
+  arguments[0] = 99; // updating arguments[0] does not also update a
+  console.log(a);
+}
+func(10); // 10
+ +

e

+ +
function func(a = 55) {
+  a = 99; // updating a does not also update arguments[0]
+  console.log(arguments[0]);
+}
+func(10); // 10
+
+ +

e

+ +
function func(a = 55) {
+  console.log(arguments[0]);
+}
+func(); // undefined
+ +

Specifiche

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Definizione iniziale. Impelementata in JavaScript 1.1
{{SpecName('ES5.1', '#sec-10.6', 'Arguments Object')}}{{Spec2('ES5.1')}} 
{{SpecName('ES2015', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ES2015')}} 
{{SpecName('ESDraft', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ESDraft')}} 
+ +

Browser compatibility

+ + + +

{{Compat("javascript.functions.arguments")}}

+ +

Si guardi anche

+ + diff --git a/files/it/web/javascript/reference/functions/arrow_functions/index.html b/files/it/web/javascript/reference/functions/arrow_functions/index.html new file mode 100644 index 0000000000..2dd258966d --- /dev/null +++ b/files/it/web/javascript/reference/functions/arrow_functions/index.html @@ -0,0 +1,394 @@ +--- +title: Funzioni a freccia +slug: Web/JavaScript/Reference/Functions_and_function_scope/Arrow_functions +tags: + - ECMAScript6 + - Funzioni + - Intermediate + - JavaScript + - Reference +translation_of: Web/JavaScript/Reference/Functions/Arrow_functions +--- +
{{jsSidebar("Functions")}}
+ +

Una funzione a freccia ha una sintassi più compatta rispetto alla notazione a funzione e non associa i propri thisargumentssuper o new.target. Le funzioni a freccia sono sempre anonime. Questa notazione è maggiormente indicata per le funzioni che non sono metodi, e non possono essere usate come costruttori.

+ +

Sintassi

+ +

Sintassi di base

+ +
(param1, param2, …, paramN) => { statements }
+(param1, param2, …, paramN) => expression
+// equivalente a: (param1, param2, …, paramN) => { return expression; }
+
+// Le Parentesi sono opzionali se è presente un solo parametro:
+(singleParam) => { statements }
+singleParam => { statements }
+
+// Una funzione senza parametri richiede comunque le parentesi:
+() => { statements }
+() => expression // equivalente a: () => { return expression; }
+
+ +

Sintassi avanzata

+ +
// Il body tra parentesi indica la restituzione di un oggetto:
+params => ({foo: bar})
+
+// Sono supportati ...rest e i parametri di default
+(param1, param2, ...rest) => { statements }
+(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements }
+
+// Si può anche destrutturare all'interno della lista dei parametri
+var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
+f();  // 6
+
+ +

Esempi dettagliati di sintassi sono disponibili qui.

+ +

Descrizione

+ +

Vedi anche "ES6 In Depth: Arrow functions" su hacks.mozilla.org.

+ +

L'introduzione delle funzioni a freccia è stata influenzata da due fattori: sintassi più compatta e la non associazione di this.

+ +

Funzioni più corte

+ +

In alcuni pattern, è meglio avere funzioni più corte. Per comparazione:

+ +
var materials = [
+  "Hydrogen",
+  "Helium",
+  "Lithium",
+  "Beryllium"
+];
+
+materials.map(function(material) {
+  return material.length;
+}); // [8, 6, 7, 9]
+
+materials.map((material) => {
+  return material.length;
+}); // [8, 6, 7, 9]
+
+materials.map(material => material.length); // [8, 6, 7, 9]
+ +

Mancato binding di this

+ +

Prima delle funzioni a freccia, ogni nuova funzione definiva il proprio  this (un nuovo oggetto nel caso di un costruttore, undefined se una funzione viene chiamata in strict mode, l'oggetto di contesto se la funzione viene chiamata come "metodo", etc.). Questo è risultato fastidioso in uno stile di programmazione orientato agli oggetti.

+ +
function Person() {
+  // The Person() constructor defines `this` as an instance of itself.
+  this.age = 0;
+
+  setInterval(function growUp() {
+    // In non-strict mode, the growUp() function defines `this`
+    // as the global object, which is different from the `this`
+    // defined by the Person() constructor.
+    this.age++;
+  }, 1000);
+}
+
+var p = new Person();
+ +

In ECMAScript 3/5, questo problema veniva aggirato assegnando il valore this a una variabile.

+ +
function Person() {
+  var that = this;
+  that.age = 0;
+
+  setInterval(function growUp() {
+    // The callback refers to the `that` variable of which
+    // the value is the expected object.
+    that.age++;
+  }, 1000);
+}
+ +

In alternativa, poteva essere usato Function.prototype.bind per assegnare il valore corretto di this da usare nella funzione  growUp().

+ +

Una funziona a freccia invece non crea  il proprio this, e quindi this mantiene il significato che aveva all'interno dello scope genitore. Perciò il codice seguente funziona come ci si aspetta.

+ +
function Person(){
+  this.age = 0;
+
+  setInterval(() => {
+    this.age++; // |this| properly refers to the person object
+  }, 1000);
+}
+
+var p = new Person();
+ +

Relazione con strict mode

+ +

Poiché  this è lessicale, le regole di strict mode relative a this sono semplicemente ignorate.

+ +
var f = () => {'use strict'; return this};
+f() === window; // o l'oggetto globale
+ +

Il resto delle regole si applica normalmente.

+ +

Invocazione attraverso call or apply

+ +

Poiché this non viene assegnato nelle funzioni a freccia, i metodi call() o apply() possono passare solo come argomenti; this viene ignorato:

+ +
var adder = {
+  base : 1,
+
+  add : function(a) {
+    var f = v => v + this.base;
+    return f(a);
+  },
+
+  addThruCall: function(a) {
+    var f = v => v + this.base;
+    var b = {
+      base : 2
+    };
+
+    return f.call(b, a);
+  }
+};
+
+console.log(adder.add(1));         // This would log to 2
+console.log(adder.addThruCall(1)); // This would log to 2 still
+ +

Mancato binding di arguments

+ +

Le funzioni a freccia non definiscono il proprio  argumentsPerciò, arguments è semplicemente una reference alla variabile nello scope genitore.

+ +
var arguments = 42;
+var arr = () => arguments;
+
+arr(); // 42
+
+function foo() {
+  var f = (i) => arguments[0]+i; // foo's implicit arguments binding
+  return f(2);
+}
+
+foo(1); // 3
+ +

Le funzioni a freccia non hanno il proprio oggetto arguments, ma in molti casi  i parametri rest rappresentano una valida alternativa:

+ +
function foo() {
+  var f = (...args) => args[0];
+  return f(2);
+}
+
+foo(1); // 2
+ +

Funzioni a freccia come metodi

+ +

Come già citato, le funzioni a freccia sono sconsigliate come metodi. Vediamo cosa succede quando proviamo a usarle: 

+ +
'use strict';
+var obj = {
+  i: 10,
+  b: () => console.log(this.i, this),
+  c: function() {
+    console.log( this.i, this)
+  }
+}
+obj.b(); // prints undefined, Window
+obj.c(); // prints 10, Object {...}
+ +

Le funzioni a freccia non definiscono  ("bind") il proprio this. un altro esempio usando {{jsxref("Object.defineProperty()")}}:

+ +
'use strict';
+var obj = {
+  a: 10
+};
+
+Object.defineProperty(obj, "b", {
+  get: () => {
+    console.log(this.a, typeof this.a, this);
+    return this.a+10; // represents global object 'Window', therefore 'this.a' returns 'undefined'
+  }
+});
+
+ +

Uso dell'operatore new 

+ +

Le funzioni a freccia non possono essere usate come costruttori, ed emetteranno un errore se usate con new.

+ +

Uso di yield 

+ +

La keyword yield non deve essere usata nel body di una funzione a freccia (eccetto quando permesso in eventuali funzioni al loro interno). Conseguentemente, le funzioni a freccia non possono essere usate come generatori.

+ +

Body della funzione

+ +

Le funzioni a freccia possono avere un "body conciso" o l'usuale "blocco body".

+ +

Nel primo caso è necessaria solo un'espressione, e il return è implicito. Nel secondo caso, devi usare esplicitamente return.

+ +
var func = x => x * x;                  // concise syntax, implied "return"
+var func = (x, y) => { return x + y; }; // with block body, explicit "return" needed
+
+ +

Restituire object literals

+ +

Tieni a mente che restituire oggetti letterali usando la sintassi concisa  params => {object:literal} non funzionerà:

+ +
var func = () => {  foo: 1  };               // Calling func() returns undefined!
+var func = () => {  foo: function() {}  };   // SyntaxError: function statement requires a name
+ +

Questo perché il codice all'interno delle parentesi graffe ({}) è processato come una sequenza di statement (i.e. foo è trattato come un label, non come una key di un oggetto).

+ +

Tuttavia, è sufficente racchiudere l'oggetto tra parentesi tonde:

+ +
var func = () => ({ foo: 1 });
+ +

Newline

+ +

Le funzioni a freccia non possono contenere un newline tra i parametri e la freccia.

+ +
var func = ()
+           => 1; // SyntaxError: expected expression, got '=>'
+ +

Ordine di parsing

+ +

La freccia in una funziona a freccia non è un'operatore, ma le funzioni a freccia hanno delle regole di parsing specifiche che interagiscono differentemente con la precedenza degli operatori, rispetto alle funzioni normali.

+ +
let callback;
+
+callback = callback || function() {}; // ok
+callback = callback || () => {};      // SyntaxError: invalid arrow-function arguments
+callback = callback || (() => {});    // ok
+
+ +

Altri esempi

+ +
// Una funzione a freccie vuota restituisce undefined
+let empty = () => {};
+
+(() => "foobar")() // IIFE, restituisce "foobar"
+
+var simple = a => a > 15 ? 15 : a;
+simple(16); // 15
+simple(10); // 10
+
+let max = (a, b) => a > b ? a : b;
+
+// Più semplice gestire filtering, mapping, ... di array
+
+var arr = [5, 6, 13, 0, 1, 18, 23];
+var sum = arr.reduce((a, b) => a + b);  // 66
+var even = arr.filter(v => v % 2 == 0); // [6, 0, 18]
+var double = arr.map(v => v * 2);       // [10, 12, 26, 0, 2, 36, 46]
+
+// Le catene di promise sono più concise
+promise.then(a => {
+  // ...
+}).then(b => {
+   // ...
+});
+
+// le funzioni a freccia senza parametri sono più semplici da visualizzare
+setTimeout( _ => {
+  console.log("I happen sooner");
+  setTimeout( _ => {
+    // deeper code
+    console.log("I happen later");
+  }, 1);
+}, 1);
+
+ +

 

+ +

 

+ +

 

+ +

Specifiche

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}{{Spec2('ESDraft')}} 
+ +

Compatibilità dei Browser 

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)EdgeIEOperaSafari
Basic support{{CompatChrome(45.0)}}{{CompatGeckoDesktop("22.0")}}{{CompatVersionUnknown}} +

{{CompatNo}}

+
{{CompatOpera(32)}}{{CompatSafari(10.0)}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidAndroid WebviewFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatNo}}{{CompatChrome(45.0)}}{{CompatGeckoMobile("22.0")}}{{CompatNo}}{{CompatNo}}{{CompatSafari(10.0)}}{{CompatChrome(45.0)}}
+
+ +

Note specifiche per Firefox

+ + + +

Vedi anche

+ + diff --git a/files/it/web/javascript/reference/functions/get/index.html b/files/it/web/javascript/reference/functions/get/index.html new file mode 100644 index 0000000000..0ed76cf469 --- /dev/null +++ b/files/it/web/javascript/reference/functions/get/index.html @@ -0,0 +1,154 @@ +--- +title: getter +slug: Web/JavaScript/Reference/Functions_and_function_scope/get +translation_of: Web/JavaScript/Reference/Functions/get +--- +
{{jsSidebar("Functions")}}
+ +

La sintassi get  associa una proprietà dell'oggetto a una funzione che verrà chiamata quando la proprietà verrà richiesta.

+ +
{{EmbedInteractiveExample("pages/js/functions-getter.html")}}
+ + + +

Sintassi

+ +
{get prop() { ... } }
+{get [expression]() { ... } }
+ +

Parametri

+ +
+
prop
+
Il nome della proprietà da associare alla funzione specificata.
+
espressione
+
A partire da ECMAScript 2015, è anche possibile utilizzare espressioni per un nome di proprietà calcolato per associarsi alla funzione specificata.
+
+ +

Descrizione

+ +

A volte è preferibile consentire l'accesso a una proprietà che restituisce un valore calcolato in modo dinamico, oppure è possibile che si desideri riflettere lo stato di una variabile interna senza richiedere l'uso di chiamate esplicite al metodo. In JavaScript, questo può essere realizzato con l'uso di un getter. Non è possibile avere simultaneamente un getter legato a una proprietà e avere quella proprietà contenuta in un valore, anche se è possibile usare un getter e un setter insieme per creare un tipo di pseudo-proprietà.

+ +

Tieni presente quanto segue quando lavori con la sintassi get:

+ +
+ +
+ +

Un getter può essere rimosso usando l'operatore  delete

+ +

Esempi

+ +

Definizione di un getter sui nuovi oggetti negli inizializzatori di oggetti

+ +

Questo creerà una pseudo-proprietà latest più recente per object obj, che restituirà l'ultimo elemento dell'array in log.

+ +
var obj = {
+  log: ['example','test'],
+  get latest() {
+    if (this.log.length == 0) return undefined;
+    return this.log[this.log.length - 1];
+  }
+}
+console.log(obj.latest); // "test".
+
+ +

Si noti che il tentativo di assegnare un valore a latest non lo cambierà.

+ +

Cancellare un getter usando l'operatore delete

+ +

Se vuoi rimuovere il getter, puoi semplicemente usare delete :

+ +
delete obj.latest;
+
+ +

Definire un getter su un oggetto esistente usando defineProperty

+ +

Per aggiungere un getter a un oggetto esistente in un secondo momento, usa {{jsxref("Object.defineProperty()")}}.

+ +
var o = {a: 0};
+
+Object.defineProperty(o, 'b', { get: function() { return this.a + 1; } });
+
+console.log(o.b) // Runs the getter, which yields a + 1 (which is 1)
+ +

Utilizzando un nome di proprietà calcolato

+ +
var expr = 'foo';
+
+var obj = {
+  get [expr]() { return 'bar'; }
+};
+
+console.log(obj.foo); // "bar"
+ +

Smart / self-overwriting / lazy getters

+ +

I getter ti danno un modo per definire una proprietà di un oggetto, ma non calcolano il valore della proprietà finché non avviene l'accesso. Un getter rinvia il costo del calcolo del valore fino a quando il valore è necessario e, se non è mai necessario, non si paga mai il costo.

+ +

Un'ulteriore tecnica di ottimizzazione per lazificare o ritardare il calcolo di un valore di una proprietà e memorizzarla nella cache per un accesso successivo sono smart o memoized getters. Il valore viene calcolato la prima volta che viene chiamato il getter e viene quindi memorizzato nella cache in modo che gli accessi successivi restituiscano il valore memorizzato nella cache senza ricalcolarlo. Questo è utile nelle seguenti situazioni:

+ + + +

Ciò significa che non si dovrebbe usare un getter pigro per una proprietà il cui valore si prevede possa cambiare, poiché il getter non ricalcola il valore.

+ +

Nell'esempio seguente, l'oggetto ha un getter come proprietà propria. Quando si ottiene la proprietà, la proprietà viene rimossa dall'oggetto e riaggiunta, ma questa volta implicitamente come proprietà dei dati. Alla fine il valore viene restituito.

+ +
get notifier() {
+  delete this.notifier;
+  return this.notifier = document.getElementById('bookmarked-notification-anchor');
+},
+ +

Per il codice di Firefox, vedere anche il modulo del codice XPCOMUtils.jsm, che definisce la funzione defineLazyGetter().

+ +

Specificazioni

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES5.1', '#sec-11.1.5', 'Object Initializer')}}{{Spec2('ES5.1')}}Definizione iniziale.
{{SpecName('ES2015', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ES2015')}}Aggiunti nomi di proprietà calcolate.
{{SpecName('ESDraft', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ESDraft')}} 
+ +

Compatibilità con il browser

+ + + +

{{Compat("javascript.functions.get")}}

+ +

Guarda anche

+ + diff --git a/files/it/web/javascript/reference/functions/index.html b/files/it/web/javascript/reference/functions/index.html new file mode 100644 index 0000000000..8a5255282c --- /dev/null +++ b/files/it/web/javascript/reference/functions/index.html @@ -0,0 +1,617 @@ +--- +title: Funzioni +slug: Web/JavaScript/Reference/Functions_and_function_scope +translation_of: Web/JavaScript/Reference/Functions +--- +
{{jsSidebar("Functions")}}
+ +

Parlando in termini generici, una funzione è un "sottopogramma" che può essere chiamato da un codice esterno (o interno nel caso di ricorsione) alla funzione stessa. Come il programma stesso, una funzione è composta da una sequenza di istruzioni chiamata corpo della funzione. Ad una funzione possono essere passati valori, e la funzione restituisce un valore.

+ +

In JavaScript, le funzioni sono oggetti di prima classe, perchè sono dotate di proprietà e di metodi, proprio come qualsiasi altro oggetto. Ciò che le distingue dagli altri oggetti è la possibilità di essere chiamate ( invocate ). Le funzioni sono oggetti di tipo Function.

+ +

Per maggiori esempi e spiegazioni, vedere anche JavaScript la guida sulle funzioni.

+ +

Descrizione

+ +

Ogni funzione in JavaScript è un oggetto di tipo Function. Vedi la pagina Function for informazioni su proprietà e metodi dell'oggetto Function.

+ +

Le funzioni non sono come le procedure. Una funzione restituisce sempre un valore, mentre una procedura può anche non restituire alcun valore.

+ +

Per restituire un valore specifico differente da quello di default, una fuzione deve avere un istruzione return che specifica il valore di ritorno. Una funzione senza un istruzione di ritorno restituirà il valore di  default. Nel caso di un costruttore invocato con la parola chiave new, il valore di default è il valore del suo parametro this. Per tutte le altre funzioni, il valore di ritorno di default è undefined.

+ +

I parametri di una chiamata di funzione sono gli argomenti della funzione. Gli argomenti sono passati alla funzione per valore. Se la funzione cambia il valore di un argomento, questo cambiamento non si riflette globalmente o nella funzione chiamante. Sebbene anche i riferimenti a oggetti siano valori, essi sono speciali: se una funzione cambia le proprietà di un oggetto a cui riferisce, quel cambiamento è visibile anche al di fuori della funzione, come dimostrato nel seguente esempio:

+ +
/* Dichiarazione della funzione 'myFunc' */
+function myFunc(theObject) {
+   theObject.brand = "Toyota";
+ }
+
+ /*
+  * Dichiarazione della variabile 'mycar';
+  * creazione e inizializzazione di un nuovo Object;
+  * associazione alla riferimento 'mycar'
+  */
+ var mycar = {
+   brand: "Honda",
+   model: "Accord",
+   year: 1998
+ };
+
+ /* Logs 'Honda' */
+ console.log(mycar.brand);
+
+ /* Passaggio del riferimento dell'oggetto alla funzione */
+ myFunc(mycar);
+
+ /*
+  * Logs 'Toyota' come il valore della proprietà 'brand'
+  * dell'oggetto, come è stato cambiato dalla funzione.
+  */
+ console.log(mycar.brand);
+
+ +

NB: l'oggetto console non è un oggetto standard. Non usatelo in un sito web, poichè potrebbe non funzionare correttamente. Per verificare il funzionamento dell'esempio precedente, usate, piuttosto:

+ +

           window.alert(mycar.brand);

+ +

La parola chiave this non fa riferimento alla funzione attualmente in esecuzione, per questo motivo si deve far riferimento ad oggetti Function  per nome, anche quando all'interno del corpo della funzione stessa.

+ +

Definizione di funzioni

+ +

Ci sono diversi modi per definire le funzioni:

+ +

La dichiarazione di funzione (istruzione function)

+ +

C'è una speciale sintassi per la dichiarazione di funzioni (per dettagli guarda function statement):

+ +
function name([param[, param[, ... param]]]) {
+   statements
+}
+
+ +
+
name
+
Il nome della funzione
+
+ +
+
param
+
Il nome di un argomento da passare alla funzione. Una funzione può avere fino a 255 argomenti.
+
+ +
+
statements
+
Le istruzioni comprese nel corpo della funzione.
+
+ +

L'espressione di funzione (espressione function)

+ +

Una espressione di funzione è simile ed ha la stessa sintassi della dichiarazione di funzione (per dettagli guarda function expression):

+ +
function [name]([param] [, param] [..., param]) {
+   statements
+}
+
+ +
+
name
+
Il nome della funzione. Può essere omesso, in qual caso la funzione è nota come funzione anonima.
+
+ +
+
param
+
Il nome di un argomento da passare alla funzione. Una funzione può avere fino a 255 argomenti.
+
statements
+
Le istruzioni comprese nel corpo della funzione.
+
+ +

La dichiarazione di funzione generatrice (espressione function*)

+ +
+

Note: Le funzioni generatrici sono un tecnologia sperimentale, parte della proposta di specifica ECMAScript 6, e non sono ancora ampiamente supportate dai browsers.

+
+ +

C'è una sintassi speciale per le funzioni generatrici (per dettagli vedi function* statement ):

+ +
function* name([param[, param[, ... param]]]) {
+   statements
+}
+
+ +
+
name
+
Nome della funzione.
+
+ +
+
param
+
Nome dell'argomento da passare alla funzione. Una funzione può avere fino a 255 agromenti.
+
+ +
+
statements
+
Le istruzioni comprese nel corpo della funzione.
+
+ +

L'espressione di funzione generatrice (espressione function*)

+ +
+

Note: Le funzioni generatrici sono una tecnologia sperimentale, parte della proposta di specifica ECMAScript 6, e non sono ancora ampiamente supportamente dai browsers.

+
+ +

Una espressione di funzione generatrice è similare ed ha la stessa sintassi di una dichiarazione di funzione generatrice (per dettagli vedi function* expression ):

+ +
function* [name]([param] [, param] [..., param]) {
+   statements
+}
+
+ +
+
name
+
Nome della funzione. Può essere omesso, nel qual caso la funzione è nota come funzione anonima.
+
+ +
+
param
+
+
Nome dell'argomento da passare alla funzione. Una funzione può avere fino a 255 agromenti.
+
+
statements
+
Le istruzioni comprese nel corpo della funzione.
+
+ +

L'espressione di funzione a freccia (=>)

+ +
+

Note: L'espressione di funzione a freccia sono una tecnologia sperimentareparte della proposta di specifica ECMAScript 6, e non sono ancora ampiamente supportate dai browsers.

+
+ +

Un' espressione di funzione a freccia ha una sintassi ridotta e lessicalmnete associa il proprio valore this (per dettagli vedere arrow functions ):

+ +
([param] [, param]) => {
+   statements
+}
+
+param => expression
+
+ +
+
param
+
Il nome di un parametro. È necessario indicare l'assenza di parametri con (). Le parentesi non sono richieste nel caso in cui ci sia solo un parametro (come foo => 1).
+
statements or expression
+
Molteplici istruzioni devono essere racchiuse tra parentesi. Una singola espressione non necessita di parantesi. expression è anche l'implicito valore restituito dalla funzione.
+
+ +

Il costruttore Function

+ +
+

Nota: l'utilizzo del costruttore Function per creare funzioni non è raccomandato, poichè richiede che il corpo della funzione sia scritto come stringa, fatto che può comportare una mancata ottimizzazione da parte di alcuni motori javascript e causare altri problemi.

+
+ +

Come tutti gli altri oggetti, un oggetto Function può essere creato utilizzando l'operatore new:

+ +
new Function (arg1, arg2, ... argN, functionBody)
+
+ +
+
arg1, arg2, ... argN
+
Zero o più nomi da usare come nomi formali di argomenti. Ciascun nome deve essere rappresentato da una stringa testuale che sia conforme alle norme che regolano la definizione di identificatori JavaScript validi, oppure da una lista di stringhe testuali, separate da una virgola; per esempio: "x", "theValue", oppure "a,b".
+
+ +
+
functionBody
+
Una stringa testuale che contenga le istruzioni Javascript comprese nella definizione della funzione.
+
+ +

Invocare il costruttore Function come funzione ( senza utilizzare l'operatore new ) ha lo stesso effetto di quando lo si invoca come costruttore.

+ +

Il costruttore GeneratorFunction

+ +
+

Nota: le espressioni di funzione a freccia ( arrow function expression ) sono una tecnologia sperimentale, parte della proposta ECMAScript 6, e non sono ancora completamente supportate dai browser.

+
+ +
+

Nota: il costruttore GeneratorFunction non è un oggetto globale, ma può essere ottenuto dall'istanza della funzione generatrice ( vedi GeneratorFunction per maggiori dettagli ).

+
+ +
+

Nota: l'utilizzo del costruttore GeneratorFunction per creare funzioni non è raccomandato, poichè richiede che il corpo della funzione sia scritto come stringa, fatto che può comportare una mancata ottimizzazione da parte di alcuni motori javascript e causare altri problemi.

+
+ +

Come tutti gli altri oggetti, un oggetto GeneratorFunction può essere creato utilizzando l'operatore new:

+ +
new GeneratorFunction (arg1, arg2, ... argN, functionBody)
+
+ +
+
arg1, arg2, ... argN
+
Zero o più nomi da usare come nomi formali di argomenti. Ciascun nome deve essere rappresentato da una stringa testuale che sia conforme alle norme che regolano la definizione di identificatori JavaScript validi, oppure da una lista di stringhe testuali, separate da una virgola; per esempio: "x", "theValue", oppure "a,b".
+
+ +
+
functionBody
+
Una stringa testuale che contenga le istruzioni Javascript comprese nella definizione della funzione.
+
+ +

Invocare il costruttore Function come funzione ( senza utilizzare l'operatore new ) ha lo stesso effetto di quando lo si invoca come costruttore.

+ +

I parametri di una funzione

+ +
+

Nota: i parametri di default ed i parametri rest sono tecnologie sperimentali, parte della proposta  ECMAScript 6, e non sono ancora completamente supportati dai browser.

+
+ +

Parametri di default

+ +

La sintassi per definire i valori di default dei parametri di una funzione permette di inizializzare i parametri formali con valori di default, sempre che non venga passato il valore undefined oppure non venga passato alcun valore. Per maggiori dettagli, vedi default parameters.

+ +

I parametri Rest

+ +

La sintassi per i parametri rest permette di rappresentare un indefinito numero di argomenti come un array. Per maggiori dettagli, vedi rest parameters.

+ +

L'oggetto arguments

+ +

È possibile riferirsi agli argomenti di una funzione, all'interno della funzione, utilizzando l'oggetto arguments. Vedi arguments.

+ + + +

Definire metodi

+ +

Funzioni Getter e setter

+ +

È possibile definire metodi getter ( accessor method: metodi per l'accesso al valore di una variabile privata ) e metodi setter ( mutator method: metodi per la modifica del valore di una variabile privata ) per qulasiasi oggetto standard built-in o per qualsiasi oggetto definito dall'utente che supporti l'aggiunta di nuove proprietà. La sintassi da usare per la definizione di metodi getter e setter utilizza la sintassi per la definizione di valori letterali.

+ +
+
get
+
+

Lega ( bind ) una proprietà di un oggetto ad una funzione, che verrà invocata ogni volta in cui si cercherà di leggere il valore di quella proprietà.

+
+
set
+
Lega ( bind ) una proprietà di un oggetto alla funzione da invocare ogni volta in cui si cercherà di modificare il valore di quella proprietà.
+
+ +

Sintassi per la definizione dei metodi

+ +
+

Nota: le definizioni dei metodi sono tecnologie sperimentali, parte della proposta  ECMAScript 6, e non sono ancora completamente supportate dai browser.

+
+ +

A partire da ECMAScript 6, è possibile definire propri metodi usando una sintassi più breve, simile alla sintassi usata per i metodi getter e setter. Vedi method definitions per maggiori informazioni.

+ +
var obj = {
+  foo() {},
+  bar() {}
+};
+ +

Il costruttore Function vs. la dichiarazione di funzione vs. l'espressione di funzione

+ +

Compara i seguenti esempi:

+ +

Una funzione definita con la dichiarazione di funzione:

+ +
function multiply(x, y) {
+   return x * y;
+}
+
+ +

Una espressione di funzione di una funzione anonima ( senza nome ), assegnata alla variabile multiply:

+ +
var multiply = function(x, y) {
+   return x * y;
+};
+
+ +

Una espressione di funzione di una funzione chiamata func_name , assegnata alla variabile multiply:

+ +
var multiply = function func_name(x, y) {
+   return x * y;
+};
+
+ +

Differenze

+ +

Tutti e tre gli esempi fanno più o meno la stessa cosa, con qualche piccola differenza:

+ +

C'è una differenza tra il nome di una funzione e la variabile alla quale la funzione viene assegnata. Il nome di una funzione non può essere modificato, mentre la variabile alla quale viene assegnata la funzione può essere riassegnata. Il nome di una funzione può essere utilizzato solo all'interno del corpo della funzione. Tentare di utilizzarlo al di fuori del corpo della funzione genererà un errore ( oppure restituirà undefined se il nome della funzione era stato precedentemente dichiarato con un'istruzione var ). Per esempio:

+ +
var y = function x() {};
+alert(x); // throws an error
+
+ +

Il nome di una funzione appare anche quando la funzione viene serializzata usando il metodo toString applicato alla funzione.

+ +

Dall'altro lato, la variabile alla quale viene assegnata la funzione è limitata solo dal suo scope, la cui inclusione è garantita al momento della dichiarazione di funzione.

+ +

Come si può vedere dal quarto esempio, il nome della funzione può essere diverso dal nome della variabile alla quale la funzione viene assegnata. I due nomi non hanno alcuna relazione tra loro. Una dichiarazione di funzione crea anche una variabile con lo stesso nome della funzione. Quindi, diversamente dalle funzioni definite attraverso un'espressione di funzione, le funzioni definite attraverso una dichiarazione di funzione offrono la possibilità di accedere ad esse attraverso il loro nome, almeno all'interno dello scope in cui erano state definite.

+ +

Una funzione definita con il costruttore 'new Function' non possiede un nome. Tuttavia, nel motore JavaScript SpiderMonkey, la forma serializzata della funzione mostra il nome "anonymous". Per esempio, il codice alert(new Function()) restituisce:

+ +
function anonymous() {
+}
+
+ +

Poichè la funzione, in realtà, non ha un nome, anonymous non è una variabile alla quale si potrà accedere, all'interno della funzione. Per esempio, il seguente codice restituirebbe un errore:

+ +
var foo = new Function("alert(anonymous);");
+foo();
+
+ +

Diversamente da quanto accade con le funzioni definite con espressioni di funzione o con il costruttore Function, una funzione definita con una dichiarazione di funzione può essere usata prima della dichiarazione di funzione stessa. Per esempio:

+ +
foo(); // alerts FOO!
+function foo() {
+   alert('FOO!');
+}
+
+ +

Una funzione definita da un'espressione di funzione eredita lo scope corrente. Vale a dire, la funzione forma una chiusura. Dall'altro lato, una funzione definita dal costruttore Function non eredita alcuno scope, se non quello globale ( che eredita qualsiasi funzione ).

+ +

Le funzioni definite con espressioni di funzione e dichiarazioni di funzione vengono analizzate ( parsed ) solo una volta, mentre quelle definite con il costruttore Function no. Vale a dire, la stringa testuale del corpo della funzione passata al costruttore Function deve essere analizzata ( parsed ) ogni volta in cui viene invocato il costruttore. Sebbene un'espressione di funzione crei ogni volta una chiusura, il corpo della funzione non viene rianalizzato ( reparsed ), così le espressioni di funzione sono ancora più veloci del "new Function(...)". Quindi, il costruttore Function dovrebbe, generalmente, essere evitato dove possibile.

+ +

Occorre tenere presente, tuttavia, che le espressioni di funzione e le dichiarazioni di funzione annidate in una funzione generata dall'analisi ( parsing ) di una stringa del costruttore Function non vengono analizzate ( parsed ) continuamente. Per esempio:

+ +
var foo = (new Function("var bar = \'FOO!\';\nreturn(function() {\n\talert(bar);\n});"))();
+foo(); // The segment "function() {\n\talert(bar);\n}" of the function body string is not re-parsed.
+ +

Una dichiarazione di funzione è molto facilmente ( e spesso, anche non intenzionalmente ) convertita in un'espressione di funzione. Una dichiarazione di funzione cessa di essere tale quando:

+ + + +
var x = 0;               // source element
+if (x == 0) {            // source element
+   x = 10;               // not a source element
+   function boo() {}     // not a source element
+}
+function foo() {         // source element
+   var y = 20;           // source element
+   function bar() {}     // source element
+   while (y == 10) {     // source element
+      function blah() {} // not a source element
+      y++;               // not a source element
+   }
+}
+
+ +

Examples

+ +
// function declaration
+function foo() {}
+
+// function expression
+(function bar() {})
+
+// function expression
+x = function hello() {}
+
+
+if (x) {
+   // function expression
+   function world() {}
+}
+
+
+// function declaration
+function a() {
+   // function declaration
+   function b() {}
+   if (0) {
+      // function expression
+      function c() {}
+   }
+}
+
+ +

Definire una funzione in modo condizionato

+ +

Le funzioni possono essere definite in modo condizionato, utilizzando sia le istruzioni di funzione ( un'estensione prevista nello standard ECMA-262 Edition 3 ), sia il costruttore Function. Da notare, però, che le  istruzioni di funzione non sono più accettate in ES5 strict mode. Inoltre, questa funzionalità non funziona bene attraverso più browser, quindi sarebbe meglio non farci affidamento.

+ +

Nello script seguente, la funzione zero non verrà mai definita e non potrà mai essere invocata, visto che 'if (0)' restituisce sempre false:

+ +
if (0) {
+   function zero() {
+      document.writeln("This is zero.");
+   }
+}
+
+ +

Se la condizione diventasse 'if (1)', la funzione zero verrebbe definita.

+ +

Nota: sebbene questo tipo di funzione sembri una dichiarazione di funzione, in realtà siamo di fronte ad una espressione ( o statement, o istruzione ), poichè la dichiarazione è annidata all'interno di un'altra istruzione. Vedi le differenze tra dichiarazioni di funzione ed espressioni di funzione.

+ +

Nota: alcuni motori JavaScript, eslcuso SpiderMonkey, trattano, non correttamente, qualsiasi espressione di funzione in modo da assegnare loro un nome, al momento della definizione. Questo comporterebbe che la funzione zero sarebbe comunque definita, anche nell'eventualità che la condizione if restituisse sempre false. Un modo più sicuro per definire le funzioni in modo condizionato è di definirle come funzioni anonime ed assegnarle, poi, ad una variabile:

+ +
if (0) {
+   var zero = function() {
+      document.writeln("This is zero.");
+   }
+}
+
+ +

Esempi

+ +

Restituire un numero formattato

+ +

La seguente funzione restituisce ( return ) una stringa contenente la rappresentazione formattata di un numero, completato ( padded ) con degli zero iniziali.

+ +
// This function returns a string padded with leading zeros
+function padZeros(num, totalLen) {
+   var numStr = num.toString();             // Initialize return value as string
+   var numZeros = totalLen - numStr.length; // Calculate no. of zeros
+   for (var i = 1; i <= numZeros; i++) {
+      numStr = "0" + numStr;
+   }
+   return numStr;
+}
+
+ +

Queste istruzioni invocano la funzione padZeros.

+ +
var result;
+result = padZeros(42,4); // returns "0042"
+result = padZeros(42,2); // returns "42"
+result = padZeros(5,4);  // returns "0005"
+
+ +

Determinare l'esistenza di una funzione

+ +

È possibile determinare se una funzione esiste, utilizzando l'operatore typeof. Nell'esempio seguente, viene eseguito un test per determinare se l'oggetto window ha una proprietà, che sia una funzione, chiamata noFunc. Se così, la funzione verrà utilizzata; in caso contrario, verrà eseguita una qualsiasi altra azione.

+ +
 if ('function' == typeof window.noFunc) {
+   // use noFunc()
+ } else {
+   // do something else
+ }
+
+ +

Da notare che nel test if  viene usato un riferimento a noFunc  — senza usare le parentesi "()" dopo il nome della funzione: in questo modo, la funzione non viene invocata.

+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition.StandardInitial definition. Implemented in JavaScript 1.0
{{SpecName('ES5.1', '#sec-13', 'Function Definition')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-function-definitions', 'Function definitions')}}{{Spec2('ES6')}}New: Arrow functions, Generator functions, default parameters, rest parameters
{{SpecName('ES6', '#', 'function*')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ES6', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}{{Spec2('ES6')}}Initial definition.
+ +

Browser compatibility

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
Generator function39{{CompatGeckoDesktop("26.0")}}{{CompatUnknown}}26{{CompatUnknown}}
Arrow function{{CompatNo}}{{CompatGeckoDesktop("22.0")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
Generator function{{CompatUnknown}}39{{CompatGeckoMobile("26.0")}}{{CompatUnknown}}26{{CompatUnknown}}
Arrow function{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("22.0")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

See also

+ + diff --git a/files/it/web/javascript/reference/functions/set/index.html b/files/it/web/javascript/reference/functions/set/index.html new file mode 100644 index 0000000000..1af0f1c79d --- /dev/null +++ b/files/it/web/javascript/reference/functions/set/index.html @@ -0,0 +1,214 @@ +--- +title: setter +slug: Web/JavaScript/Reference/Functions_and_function_scope/set +tags: + - Funzioni + - JavaScript + - setter +translation_of: Web/JavaScript/Reference/Functions/set +--- +
{{jsSidebar("Functions")}}
+ +

Il costrutto sintattico set collega una proprietà di un oggetto ad una funzione che viene chiamata quando si ha un tentativo di modifica di quella proprietà.

+ +

Sintassi

+ +
{set prop(val) { . . . }}
+{set [expression](val) { . . . }}
+ +

Parametri

+ +
+
prop
+
Il nome della proprietà da collegare alla funzione data.
+
+ +
+
val
+
Un alias per la variabile che contiene il valore che si sta cercando di assegnare a prop.
+
expression
+
A partire da ECMAScript 6, è possibile anche usare espressioni per nomi di proprietà computate da collegare alla funzione data.
+
+ +

Descrizione

+ +

In JavaScript, un setter può essere utilizzato per eseguire una funzione ogniqualvolta una proprietà specificata sta per essere modificata. I setters sono quasi sempre utilizzati insieme ai getters per creare un tipo di pseudo proprietà. Non è possibile avere un setter su una normale proprietà che contiene un valore.

+ +

Alcune note da considerare quando si utilizza il costrutto sintattico set:

+ +
+ +
+ +

Un setter può essere eliminato usando l'operatore delete.

+ +

Esempi

+ +

Definire un setter per nuovi oggetti in inizializzatori di oggetti

+ +

Questo snippet di codice definisce una pseudo proprietà current di un oggetto che, una volta che vi si assegna un valore, aggiornerà log con quel valore:

+ +
var o = {
+  set current (str) {
+    this.log[this.log.length] = str;
+  },
+  log: []
+}
+
+ +

Nota che  current non è definito ed ogni tentativo di accedervi risulterà in un undefined.

+ +

Rimuovere un setter con l'operatore delete

+ +

Se vuoi rimuovere il setter usato sopra, puoi semplicemente usare delete:

+ +
delete o.current;
+
+ +

Definire un setter su oggetti pre-esistenti usando defineProperty

+ +

Per aggiungere un setter ad un oggetto pre-esistente, usa{{jsxref("Object.defineProperty()")}}.

+ +
var o = { a:0 };
+
+Object.defineProperty(o, "b", { set: function (x) { this.a = x / 2; } });
+
+o.b = 10; // Runs the setter, which assigns 10 / 2 (5) to the 'a' property
+console.log(o.a) // 5
+ +

Usare il nome di una proprietà computata

+ +
+

Nota: Le proprietà computate sono una tecnologia sperimentale, parte dello standard proposto ECMAScript 6, e non sono ancora sufficientemente supportate dai browsers. L'uso di queste proprietà in ambienti che non le supportano produrrà un errore di sintassi.

+
+ +
var expr = "foo";
+
+var obj = {
+  baz: "bar",
+  set [expr](v) { this.baz = v; }
+};
+
+console.log(obj.baz); // "bar"
+obj.foo = "baz";      // run the setter
+console.log(obj.baz); // "baz"
+
+ +

Specifiche

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificaStatusCommento
{{SpecName('ES5.1', '#sec-11.1.5', 'Object Initializer')}}{{Spec2('ES5.1')}}Definizione iniziale.
{{SpecName('ES6', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ES6')}}Aggiunti i nomi di proprietà computate.
{{SpecName('ESDraft', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ESDraft')}}
+ +

Compatibilità dei browsers

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
CaratteristicaChromeFirefox (Gecko)Internet ExplorerOperaSafari
Supporto base{{CompatChrome(1)}}{{ CompatGeckoDesktop("1.8.1") }}{{ CompatIE(9) }}9.53
Nomi di proprietà computate{{CompatNo}}{{ CompatGeckoDesktop("34") }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CaratteristicaAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Supporto base{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{ CompatGeckoMobile("1.8.1") }}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
Nomi di proprietà computate{{CompatNo}}{{CompatNo}}{{ CompatGeckoMobile("34.0") }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

Note specifiche per SpiderMonkey

+ + + +

Guarda anche

+ + diff --git a/files/it/web/javascript/reference/functions_and_function_scope/arguments/index.html b/files/it/web/javascript/reference/functions_and_function_scope/arguments/index.html deleted file mode 100644 index c277074bca..0000000000 --- a/files/it/web/javascript/reference/functions_and_function_scope/arguments/index.html +++ /dev/null @@ -1,224 +0,0 @@ ---- -title: Oggetto 'arguments' -slug: Web/JavaScript/Reference/Functions_and_function_scope/arguments -translation_of: Web/JavaScript/Reference/Functions/arguments ---- -
-
{{jsSidebar("Functions")}}
-
- -

L'oggetto arguments è un oggetto Array-like corrispondente agli argomenti passati in una funzione 

- -

{{EmbedInteractiveExample("pages/js/functions-arguments.html")}}

- - - -

Sintassi

- -
arguments
- -

Descrizione

- -

L'oggetto arguments è una variabile locale disponibile in tutte le funzioni (non-arrow). Si può fare riferimento agli argomenti di una funzione, al suo interno, usando l'oggetto  arguments. Questo oggetto contiene un elemento per ogni argomento passato alla funzione, il primo elemento è indicizzato a 0. Per esempio, se a una funzione sono passati tre argomenti, ci si può riferire ad essi come segue:

- -
arguments[0]
-arguments[1]
-arguments[2]
-
- -

Gli argomenti possono anche essere settati:

- -
arguments[1] = 'nuovo valore';
-
- -

L'oggetto arguments non è un {{jsxref("Array")}}. E' simile a un  Array, ma non ha le proprietà dell'Array, eccetto length. Per esempio, non ha il metodo pop. Tuttavia può essere convertito in un vero Array:

- -
var args = Array.prototype.slice.call(arguments);
-var args = [].slice.call(arguments);
-
-// ES2015
-const args = Array.from(arguments);
-
- -
-

Usare slice su arguments impedisce le ottimizzazioni in alcuni motori JavaScript (per esempio V8 - più informazioni). Se ne avete bisogno, provate a costruire un nuovo array iterando sull'oggetto arguments, piuttosto. Un'alternativa potrebbe essere usare l'odiato costruttore Array come una funzione:

- -
var args = (arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments));
-
- -

Si può usare l'oggetto arguments se si chiama una funzione con più argomenti di quanti la funzione dichiari formalmente di accettare. Questa tecnica è utile per le funzioni cui possono essere passati un numero variabile di argomenti. Si usi arguments.length per determinare il numero di argomenti passati alla funzione, e quindi si processi ogni argomento usando l'oggetto arguments. Per determinare il numero di parametri presenti nella dichiarazione di una funzione, si usi la proprietà Function.length.

- -

Usare typeof con Arguments

- -

Il typeof di arguments ritorna 'object'. 

- -
console.log(typeof arguments); // 'object' 
- -

Il typeof di ogni signolo argomento può essere determinato con l'uso degli indici.

- -
console.log(typeof arguments[0]); //this will return the typeof individual arguments.
- -

Usare la sintassi Spread con Arguments

- -

Come è possibile fare con qualsiasi oggetto Array-like, si può usare il metodo {{jsxref("Array.from()")}} o lo spread operator per convertire arguments in un vero Array:

- -
var args = Array.from(arguments);
-var args = [...arguments];
-
- -

Proprietà

- -
-
arguments.callee
-
Riferimento alla funzione in esecuzione.
-
arguments.caller {{ Obsolete_inline() }}
-
Riferimento alla funzione che ha invocato la funzione in esecuzione.
-
arguments.length
-
Riferimento al numero di argomenti passati alla funzione.
-
arguments[@@iterator]
-
Ritorna un nuovo oggetto Array Iterator che contiene i valori per ogni indice in arguments.
-
- -

Esempi

- -

Definire una funzione che concatena divere stringhe 

- -

Questo esempio definisce una funzione che concatena diverse stringhe. L'unico argomento formale per la funzione è una stringa che specifica il carattere di separazione per gli elementi da concatenare. La funzione si definisce come segue:

- -
function myConcat(separator) {
-  var args = Array.prototype.slice.call(arguments, 1);
-  return args.join(separator);
-}
- -

Si può passare un numero indefinito di argomenti a questa funzione, e lei creerà una lista inserendo ciascun argomento come item della lista. 

- -
// returns "red, orange, blue"
-myConcat(', ', 'red', 'orange', 'blue');
-
-// returns "elephant; giraffe; lion; cheetah"
-myConcat('; ', 'elephant', 'giraffe', 'lion', 'cheetah');
-
-// returns "sage. basil. oregano. pepper. parsley"
-myConcat('. ', 'sage', 'basil', 'oregano', 'pepper', 'parsley');
- -

Definire una funzione che crea liste HTML

- -

Questo esempio definisce una funzione che crea una stringa contenente l'HTML di una lista. L'unico argomento formale della funzione è una  stringa che è "u" se la lista deve essere ordinata, e "o" se la lista deve essere ordinata (numerata). La funzione è definita come segue:

- -
function list(type) {
-  var result = '<' + type + 'l><li>';
-  var args = Array.prototype.slice.call(arguments, 1);
-  result += args.join('</li><li>');
-  result += '</li></' + type + 'l>'; // end list
-
-  return result;
-}
- -

Si può passare un numero indefinito di argomenti a questa funzione, e lei aggiungerà ogni argomento come un elemento della lista del tipo indicato. Per esempio:

- -
var listHTML = list('u', 'One', 'Two', 'Three');
-
-/* listHTML is:
-
-"<ul><li>One</li><li>Two</li><li>Three</li></ul>"
-
-*/
- -

Parametri rest, default, e destructured

- -

L'oggetto arguments può essere usato insieme a parametri rest, default, e destructured.

- -
function foo(...args) {
-  return args;
-}
-foo(1, 2, 3); // [1,2,3]
-
- -

Sebbene la presenza di parametri restdefault, o destructured non altera il comportamento dell'oggetto arguments nel codice scritto in strict mode, c'è una sottile differenza tra modalità strict e non-strict.

- -

Quando una funzione non-strict non contiene parametri restdefault, o destructured, allora i valori nell'oggetto arguments  tracciano il valore degli argomenti (e vice versa). Si guardi il codice qui sotto:

- -
function func(a) {
-  arguments[0] = 99; // updating arguments[0] also updates a
-  console.log(a);
-}
-func(10); // 99
-
- -

e

- -
function func(a) {
-  a = 99; // updating a also updates arguments[0]
-  console.log(arguments[0]);
-}
-func(10); // 99
-
- -

Quando una funzione non-strict contiene parametri restdefault, o destructured, allora i valori nell'oggetto arguments non tracciano il valore degli argomenti (e vice versa). Al contrario, riflettono gli argomenti forniti al momento dell'invocazione:

- -
function func(a = 55) {
-  arguments[0] = 99; // updating arguments[0] does not also update a
-  console.log(a);
-}
-func(10); // 10
- -

e

- -
function func(a = 55) {
-  a = 99; // updating a does not also update arguments[0]
-  console.log(arguments[0]);
-}
-func(10); // 10
-
- -

e

- -
function func(a = 55) {
-  console.log(arguments[0]);
-}
-func(); // undefined
- -

Specifiche

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Definizione iniziale. Impelementata in JavaScript 1.1
{{SpecName('ES5.1', '#sec-10.6', 'Arguments Object')}}{{Spec2('ES5.1')}} 
{{SpecName('ES2015', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ES2015')}} 
{{SpecName('ESDraft', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}{{Spec2('ESDraft')}} 
- -

Browser compatibility

- - - -

{{Compat("javascript.functions.arguments")}}

- -

Si guardi anche

- - diff --git a/files/it/web/javascript/reference/functions_and_function_scope/arrow_functions/index.html b/files/it/web/javascript/reference/functions_and_function_scope/arrow_functions/index.html deleted file mode 100644 index 2dd258966d..0000000000 --- a/files/it/web/javascript/reference/functions_and_function_scope/arrow_functions/index.html +++ /dev/null @@ -1,394 +0,0 @@ ---- -title: Funzioni a freccia -slug: Web/JavaScript/Reference/Functions_and_function_scope/Arrow_functions -tags: - - ECMAScript6 - - Funzioni - - Intermediate - - JavaScript - - Reference -translation_of: Web/JavaScript/Reference/Functions/Arrow_functions ---- -
{{jsSidebar("Functions")}}
- -

Una funzione a freccia ha una sintassi più compatta rispetto alla notazione a funzione e non associa i propri thisargumentssuper o new.target. Le funzioni a freccia sono sempre anonime. Questa notazione è maggiormente indicata per le funzioni che non sono metodi, e non possono essere usate come costruttori.

- -

Sintassi

- -

Sintassi di base

- -
(param1, param2, …, paramN) => { statements }
-(param1, param2, …, paramN) => expression
-// equivalente a: (param1, param2, …, paramN) => { return expression; }
-
-// Le Parentesi sono opzionali se è presente un solo parametro:
-(singleParam) => { statements }
-singleParam => { statements }
-
-// Una funzione senza parametri richiede comunque le parentesi:
-() => { statements }
-() => expression // equivalente a: () => { return expression; }
-
- -

Sintassi avanzata

- -
// Il body tra parentesi indica la restituzione di un oggetto:
-params => ({foo: bar})
-
-// Sono supportati ...rest e i parametri di default
-(param1, param2, ...rest) => { statements }
-(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements }
-
-// Si può anche destrutturare all'interno della lista dei parametri
-var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
-f();  // 6
-
- -

Esempi dettagliati di sintassi sono disponibili qui.

- -

Descrizione

- -

Vedi anche "ES6 In Depth: Arrow functions" su hacks.mozilla.org.

- -

L'introduzione delle funzioni a freccia è stata influenzata da due fattori: sintassi più compatta e la non associazione di this.

- -

Funzioni più corte

- -

In alcuni pattern, è meglio avere funzioni più corte. Per comparazione:

- -
var materials = [
-  "Hydrogen",
-  "Helium",
-  "Lithium",
-  "Beryllium"
-];
-
-materials.map(function(material) {
-  return material.length;
-}); // [8, 6, 7, 9]
-
-materials.map((material) => {
-  return material.length;
-}); // [8, 6, 7, 9]
-
-materials.map(material => material.length); // [8, 6, 7, 9]
- -

Mancato binding di this

- -

Prima delle funzioni a freccia, ogni nuova funzione definiva il proprio  this (un nuovo oggetto nel caso di un costruttore, undefined se una funzione viene chiamata in strict mode, l'oggetto di contesto se la funzione viene chiamata come "metodo", etc.). Questo è risultato fastidioso in uno stile di programmazione orientato agli oggetti.

- -
function Person() {
-  // The Person() constructor defines `this` as an instance of itself.
-  this.age = 0;
-
-  setInterval(function growUp() {
-    // In non-strict mode, the growUp() function defines `this`
-    // as the global object, which is different from the `this`
-    // defined by the Person() constructor.
-    this.age++;
-  }, 1000);
-}
-
-var p = new Person();
- -

In ECMAScript 3/5, questo problema veniva aggirato assegnando il valore this a una variabile.

- -
function Person() {
-  var that = this;
-  that.age = 0;
-
-  setInterval(function growUp() {
-    // The callback refers to the `that` variable of which
-    // the value is the expected object.
-    that.age++;
-  }, 1000);
-}
- -

In alternativa, poteva essere usato Function.prototype.bind per assegnare il valore corretto di this da usare nella funzione  growUp().

- -

Una funziona a freccia invece non crea  il proprio this, e quindi this mantiene il significato che aveva all'interno dello scope genitore. Perciò il codice seguente funziona come ci si aspetta.

- -
function Person(){
-  this.age = 0;
-
-  setInterval(() => {
-    this.age++; // |this| properly refers to the person object
-  }, 1000);
-}
-
-var p = new Person();
- -

Relazione con strict mode

- -

Poiché  this è lessicale, le regole di strict mode relative a this sono semplicemente ignorate.

- -
var f = () => {'use strict'; return this};
-f() === window; // o l'oggetto globale
- -

Il resto delle regole si applica normalmente.

- -

Invocazione attraverso call or apply

- -

Poiché this non viene assegnato nelle funzioni a freccia, i metodi call() o apply() possono passare solo come argomenti; this viene ignorato:

- -
var adder = {
-  base : 1,
-
-  add : function(a) {
-    var f = v => v + this.base;
-    return f(a);
-  },
-
-  addThruCall: function(a) {
-    var f = v => v + this.base;
-    var b = {
-      base : 2
-    };
-
-    return f.call(b, a);
-  }
-};
-
-console.log(adder.add(1));         // This would log to 2
-console.log(adder.addThruCall(1)); // This would log to 2 still
- -

Mancato binding di arguments

- -

Le funzioni a freccia non definiscono il proprio  argumentsPerciò, arguments è semplicemente una reference alla variabile nello scope genitore.

- -
var arguments = 42;
-var arr = () => arguments;
-
-arr(); // 42
-
-function foo() {
-  var f = (i) => arguments[0]+i; // foo's implicit arguments binding
-  return f(2);
-}
-
-foo(1); // 3
- -

Le funzioni a freccia non hanno il proprio oggetto arguments, ma in molti casi  i parametri rest rappresentano una valida alternativa:

- -
function foo() {
-  var f = (...args) => args[0];
-  return f(2);
-}
-
-foo(1); // 2
- -

Funzioni a freccia come metodi

- -

Come già citato, le funzioni a freccia sono sconsigliate come metodi. Vediamo cosa succede quando proviamo a usarle: 

- -
'use strict';
-var obj = {
-  i: 10,
-  b: () => console.log(this.i, this),
-  c: function() {
-    console.log( this.i, this)
-  }
-}
-obj.b(); // prints undefined, Window
-obj.c(); // prints 10, Object {...}
- -

Le funzioni a freccia non definiscono  ("bind") il proprio this. un altro esempio usando {{jsxref("Object.defineProperty()")}}:

- -
'use strict';
-var obj = {
-  a: 10
-};
-
-Object.defineProperty(obj, "b", {
-  get: () => {
-    console.log(this.a, typeof this.a, this);
-    return this.a+10; // represents global object 'Window', therefore 'this.a' returns 'undefined'
-  }
-});
-
- -

Uso dell'operatore new 

- -

Le funzioni a freccia non possono essere usate come costruttori, ed emetteranno un errore se usate con new.

- -

Uso di yield 

- -

La keyword yield non deve essere usata nel body di una funzione a freccia (eccetto quando permesso in eventuali funzioni al loro interno). Conseguentemente, le funzioni a freccia non possono essere usate come generatori.

- -

Body della funzione

- -

Le funzioni a freccia possono avere un "body conciso" o l'usuale "blocco body".

- -

Nel primo caso è necessaria solo un'espressione, e il return è implicito. Nel secondo caso, devi usare esplicitamente return.

- -
var func = x => x * x;                  // concise syntax, implied "return"
-var func = (x, y) => { return x + y; }; // with block body, explicit "return" needed
-
- -

Restituire object literals

- -

Tieni a mente che restituire oggetti letterali usando la sintassi concisa  params => {object:literal} non funzionerà:

- -
var func = () => {  foo: 1  };               // Calling func() returns undefined!
-var func = () => {  foo: function() {}  };   // SyntaxError: function statement requires a name
- -

Questo perché il codice all'interno delle parentesi graffe ({}) è processato come una sequenza di statement (i.e. foo è trattato come un label, non come una key di un oggetto).

- -

Tuttavia, è sufficente racchiudere l'oggetto tra parentesi tonde:

- -
var func = () => ({ foo: 1 });
- -

Newline

- -

Le funzioni a freccia non possono contenere un newline tra i parametri e la freccia.

- -
var func = ()
-           => 1; // SyntaxError: expected expression, got '=>'
- -

Ordine di parsing

- -

La freccia in una funziona a freccia non è un'operatore, ma le funzioni a freccia hanno delle regole di parsing specifiche che interagiscono differentemente con la precedenza degli operatori, rispetto alle funzioni normali.

- -
let callback;
-
-callback = callback || function() {}; // ok
-callback = callback || () => {};      // SyntaxError: invalid arrow-function arguments
-callback = callback || (() => {});    // ok
-
- -

Altri esempi

- -
// Una funzione a freccie vuota restituisce undefined
-let empty = () => {};
-
-(() => "foobar")() // IIFE, restituisce "foobar"
-
-var simple = a => a > 15 ? 15 : a;
-simple(16); // 15
-simple(10); // 10
-
-let max = (a, b) => a > b ? a : b;
-
-// Più semplice gestire filtering, mapping, ... di array
-
-var arr = [5, 6, 13, 0, 1, 18, 23];
-var sum = arr.reduce((a, b) => a + b);  // 66
-var even = arr.filter(v => v % 2 == 0); // [6, 0, 18]
-var double = arr.map(v => v * 2);       // [10, 12, 26, 0, 2, 36, 46]
-
-// Le catene di promise sono più concise
-promise.then(a => {
-  // ...
-}).then(b => {
-   // ...
-});
-
-// le funzioni a freccia senza parametri sono più semplici da visualizzare
-setTimeout( _ => {
-  console.log("I happen sooner");
-  setTimeout( _ => {
-    // deeper code
-    console.log("I happen later");
-  }, 1);
-}, 1);
-
- -

 

- -

 

- -

 

- -

Specifiche

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES6', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}{{Spec2('ESDraft')}} 
- -

Compatibilità dei Browser 

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)EdgeIEOperaSafari
Basic support{{CompatChrome(45.0)}}{{CompatGeckoDesktop("22.0")}}{{CompatVersionUnknown}} -

{{CompatNo}}

-
{{CompatOpera(32)}}{{CompatSafari(10.0)}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidAndroid WebviewFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatNo}}{{CompatChrome(45.0)}}{{CompatGeckoMobile("22.0")}}{{CompatNo}}{{CompatNo}}{{CompatSafari(10.0)}}{{CompatChrome(45.0)}}
-
- -

Note specifiche per Firefox

- - - -

Vedi anche

- - diff --git a/files/it/web/javascript/reference/functions_and_function_scope/get/index.html b/files/it/web/javascript/reference/functions_and_function_scope/get/index.html deleted file mode 100644 index 0ed76cf469..0000000000 --- a/files/it/web/javascript/reference/functions_and_function_scope/get/index.html +++ /dev/null @@ -1,154 +0,0 @@ ---- -title: getter -slug: Web/JavaScript/Reference/Functions_and_function_scope/get -translation_of: Web/JavaScript/Reference/Functions/get ---- -
{{jsSidebar("Functions")}}
- -

La sintassi get  associa una proprietà dell'oggetto a una funzione che verrà chiamata quando la proprietà verrà richiesta.

- -
{{EmbedInteractiveExample("pages/js/functions-getter.html")}}
- - - -

Sintassi

- -
{get prop() { ... } }
-{get [expression]() { ... } }
- -

Parametri

- -
-
prop
-
Il nome della proprietà da associare alla funzione specificata.
-
espressione
-
A partire da ECMAScript 2015, è anche possibile utilizzare espressioni per un nome di proprietà calcolato per associarsi alla funzione specificata.
-
- -

Descrizione

- -

A volte è preferibile consentire l'accesso a una proprietà che restituisce un valore calcolato in modo dinamico, oppure è possibile che si desideri riflettere lo stato di una variabile interna senza richiedere l'uso di chiamate esplicite al metodo. In JavaScript, questo può essere realizzato con l'uso di un getter. Non è possibile avere simultaneamente un getter legato a una proprietà e avere quella proprietà contenuta in un valore, anche se è possibile usare un getter e un setter insieme per creare un tipo di pseudo-proprietà.

- -

Tieni presente quanto segue quando lavori con la sintassi get:

- -
- -
- -

Un getter può essere rimosso usando l'operatore  delete

- -

Esempi

- -

Definizione di un getter sui nuovi oggetti negli inizializzatori di oggetti

- -

Questo creerà una pseudo-proprietà latest più recente per object obj, che restituirà l'ultimo elemento dell'array in log.

- -
var obj = {
-  log: ['example','test'],
-  get latest() {
-    if (this.log.length == 0) return undefined;
-    return this.log[this.log.length - 1];
-  }
-}
-console.log(obj.latest); // "test".
-
- -

Si noti che il tentativo di assegnare un valore a latest non lo cambierà.

- -

Cancellare un getter usando l'operatore delete

- -

Se vuoi rimuovere il getter, puoi semplicemente usare delete :

- -
delete obj.latest;
-
- -

Definire un getter su un oggetto esistente usando defineProperty

- -

Per aggiungere un getter a un oggetto esistente in un secondo momento, usa {{jsxref("Object.defineProperty()")}}.

- -
var o = {a: 0};
-
-Object.defineProperty(o, 'b', { get: function() { return this.a + 1; } });
-
-console.log(o.b) // Runs the getter, which yields a + 1 (which is 1)
- -

Utilizzando un nome di proprietà calcolato

- -
var expr = 'foo';
-
-var obj = {
-  get [expr]() { return 'bar'; }
-};
-
-console.log(obj.foo); // "bar"
- -

Smart / self-overwriting / lazy getters

- -

I getter ti danno un modo per definire una proprietà di un oggetto, ma non calcolano il valore della proprietà finché non avviene l'accesso. Un getter rinvia il costo del calcolo del valore fino a quando il valore è necessario e, se non è mai necessario, non si paga mai il costo.

- -

Un'ulteriore tecnica di ottimizzazione per lazificare o ritardare il calcolo di un valore di una proprietà e memorizzarla nella cache per un accesso successivo sono smart o memoized getters. Il valore viene calcolato la prima volta che viene chiamato il getter e viene quindi memorizzato nella cache in modo che gli accessi successivi restituiscano il valore memorizzato nella cache senza ricalcolarlo. Questo è utile nelle seguenti situazioni:

- - - -

Ciò significa che non si dovrebbe usare un getter pigro per una proprietà il cui valore si prevede possa cambiare, poiché il getter non ricalcola il valore.

- -

Nell'esempio seguente, l'oggetto ha un getter come proprietà propria. Quando si ottiene la proprietà, la proprietà viene rimossa dall'oggetto e riaggiunta, ma questa volta implicitamente come proprietà dei dati. Alla fine il valore viene restituito.

- -
get notifier() {
-  delete this.notifier;
-  return this.notifier = document.getElementById('bookmarked-notification-anchor');
-},
- -

Per il codice di Firefox, vedere anche il modulo del codice XPCOMUtils.jsm, che definisce la funzione defineLazyGetter().

- -

Specificazioni

- - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES5.1', '#sec-11.1.5', 'Object Initializer')}}{{Spec2('ES5.1')}}Definizione iniziale.
{{SpecName('ES2015', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ES2015')}}Aggiunti nomi di proprietà calcolate.
{{SpecName('ESDraft', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ESDraft')}} 
- -

Compatibilità con il browser

- - - -

{{Compat("javascript.functions.get")}}

- -

Guarda anche

- - diff --git a/files/it/web/javascript/reference/functions_and_function_scope/index.html b/files/it/web/javascript/reference/functions_and_function_scope/index.html deleted file mode 100644 index 8a5255282c..0000000000 --- a/files/it/web/javascript/reference/functions_and_function_scope/index.html +++ /dev/null @@ -1,617 +0,0 @@ ---- -title: Funzioni -slug: Web/JavaScript/Reference/Functions_and_function_scope -translation_of: Web/JavaScript/Reference/Functions ---- -
{{jsSidebar("Functions")}}
- -

Parlando in termini generici, una funzione è un "sottopogramma" che può essere chiamato da un codice esterno (o interno nel caso di ricorsione) alla funzione stessa. Come il programma stesso, una funzione è composta da una sequenza di istruzioni chiamata corpo della funzione. Ad una funzione possono essere passati valori, e la funzione restituisce un valore.

- -

In JavaScript, le funzioni sono oggetti di prima classe, perchè sono dotate di proprietà e di metodi, proprio come qualsiasi altro oggetto. Ciò che le distingue dagli altri oggetti è la possibilità di essere chiamate ( invocate ). Le funzioni sono oggetti di tipo Function.

- -

Per maggiori esempi e spiegazioni, vedere anche JavaScript la guida sulle funzioni.

- -

Descrizione

- -

Ogni funzione in JavaScript è un oggetto di tipo Function. Vedi la pagina Function for informazioni su proprietà e metodi dell'oggetto Function.

- -

Le funzioni non sono come le procedure. Una funzione restituisce sempre un valore, mentre una procedura può anche non restituire alcun valore.

- -

Per restituire un valore specifico differente da quello di default, una fuzione deve avere un istruzione return che specifica il valore di ritorno. Una funzione senza un istruzione di ritorno restituirà il valore di  default. Nel caso di un costruttore invocato con la parola chiave new, il valore di default è il valore del suo parametro this. Per tutte le altre funzioni, il valore di ritorno di default è undefined.

- -

I parametri di una chiamata di funzione sono gli argomenti della funzione. Gli argomenti sono passati alla funzione per valore. Se la funzione cambia il valore di un argomento, questo cambiamento non si riflette globalmente o nella funzione chiamante. Sebbene anche i riferimenti a oggetti siano valori, essi sono speciali: se una funzione cambia le proprietà di un oggetto a cui riferisce, quel cambiamento è visibile anche al di fuori della funzione, come dimostrato nel seguente esempio:

- -
/* Dichiarazione della funzione 'myFunc' */
-function myFunc(theObject) {
-   theObject.brand = "Toyota";
- }
-
- /*
-  * Dichiarazione della variabile 'mycar';
-  * creazione e inizializzazione di un nuovo Object;
-  * associazione alla riferimento 'mycar'
-  */
- var mycar = {
-   brand: "Honda",
-   model: "Accord",
-   year: 1998
- };
-
- /* Logs 'Honda' */
- console.log(mycar.brand);
-
- /* Passaggio del riferimento dell'oggetto alla funzione */
- myFunc(mycar);
-
- /*
-  * Logs 'Toyota' come il valore della proprietà 'brand'
-  * dell'oggetto, come è stato cambiato dalla funzione.
-  */
- console.log(mycar.brand);
-
- -

NB: l'oggetto console non è un oggetto standard. Non usatelo in un sito web, poichè potrebbe non funzionare correttamente. Per verificare il funzionamento dell'esempio precedente, usate, piuttosto:

- -

           window.alert(mycar.brand);

- -

La parola chiave this non fa riferimento alla funzione attualmente in esecuzione, per questo motivo si deve far riferimento ad oggetti Function  per nome, anche quando all'interno del corpo della funzione stessa.

- -

Definizione di funzioni

- -

Ci sono diversi modi per definire le funzioni:

- -

La dichiarazione di funzione (istruzione function)

- -

C'è una speciale sintassi per la dichiarazione di funzioni (per dettagli guarda function statement):

- -
function name([param[, param[, ... param]]]) {
-   statements
-}
-
- -
-
name
-
Il nome della funzione
-
- -
-
param
-
Il nome di un argomento da passare alla funzione. Una funzione può avere fino a 255 argomenti.
-
- -
-
statements
-
Le istruzioni comprese nel corpo della funzione.
-
- -

L'espressione di funzione (espressione function)

- -

Una espressione di funzione è simile ed ha la stessa sintassi della dichiarazione di funzione (per dettagli guarda function expression):

- -
function [name]([param] [, param] [..., param]) {
-   statements
-}
-
- -
-
name
-
Il nome della funzione. Può essere omesso, in qual caso la funzione è nota come funzione anonima.
-
- -
-
param
-
Il nome di un argomento da passare alla funzione. Una funzione può avere fino a 255 argomenti.
-
statements
-
Le istruzioni comprese nel corpo della funzione.
-
- -

La dichiarazione di funzione generatrice (espressione function*)

- -
-

Note: Le funzioni generatrici sono un tecnologia sperimentale, parte della proposta di specifica ECMAScript 6, e non sono ancora ampiamente supportate dai browsers.

-
- -

C'è una sintassi speciale per le funzioni generatrici (per dettagli vedi function* statement ):

- -
function* name([param[, param[, ... param]]]) {
-   statements
-}
-
- -
-
name
-
Nome della funzione.
-
- -
-
param
-
Nome dell'argomento da passare alla funzione. Una funzione può avere fino a 255 agromenti.
-
- -
-
statements
-
Le istruzioni comprese nel corpo della funzione.
-
- -

L'espressione di funzione generatrice (espressione function*)

- -
-

Note: Le funzioni generatrici sono una tecnologia sperimentale, parte della proposta di specifica ECMAScript 6, e non sono ancora ampiamente supportamente dai browsers.

-
- -

Una espressione di funzione generatrice è similare ed ha la stessa sintassi di una dichiarazione di funzione generatrice (per dettagli vedi function* expression ):

- -
function* [name]([param] [, param] [..., param]) {
-   statements
-}
-
- -
-
name
-
Nome della funzione. Può essere omesso, nel qual caso la funzione è nota come funzione anonima.
-
- -
-
param
-
-
Nome dell'argomento da passare alla funzione. Una funzione può avere fino a 255 agromenti.
-
-
statements
-
Le istruzioni comprese nel corpo della funzione.
-
- -

L'espressione di funzione a freccia (=>)

- -
-

Note: L'espressione di funzione a freccia sono una tecnologia sperimentareparte della proposta di specifica ECMAScript 6, e non sono ancora ampiamente supportate dai browsers.

-
- -

Un' espressione di funzione a freccia ha una sintassi ridotta e lessicalmnete associa il proprio valore this (per dettagli vedere arrow functions ):

- -
([param] [, param]) => {
-   statements
-}
-
-param => expression
-
- -
-
param
-
Il nome di un parametro. È necessario indicare l'assenza di parametri con (). Le parentesi non sono richieste nel caso in cui ci sia solo un parametro (come foo => 1).
-
statements or expression
-
Molteplici istruzioni devono essere racchiuse tra parentesi. Una singola espressione non necessita di parantesi. expression è anche l'implicito valore restituito dalla funzione.
-
- -

Il costruttore Function

- -
-

Nota: l'utilizzo del costruttore Function per creare funzioni non è raccomandato, poichè richiede che il corpo della funzione sia scritto come stringa, fatto che può comportare una mancata ottimizzazione da parte di alcuni motori javascript e causare altri problemi.

-
- -

Come tutti gli altri oggetti, un oggetto Function può essere creato utilizzando l'operatore new:

- -
new Function (arg1, arg2, ... argN, functionBody)
-
- -
-
arg1, arg2, ... argN
-
Zero o più nomi da usare come nomi formali di argomenti. Ciascun nome deve essere rappresentato da una stringa testuale che sia conforme alle norme che regolano la definizione di identificatori JavaScript validi, oppure da una lista di stringhe testuali, separate da una virgola; per esempio: "x", "theValue", oppure "a,b".
-
- -
-
functionBody
-
Una stringa testuale che contenga le istruzioni Javascript comprese nella definizione della funzione.
-
- -

Invocare il costruttore Function come funzione ( senza utilizzare l'operatore new ) ha lo stesso effetto di quando lo si invoca come costruttore.

- -

Il costruttore GeneratorFunction

- -
-

Nota: le espressioni di funzione a freccia ( arrow function expression ) sono una tecnologia sperimentale, parte della proposta ECMAScript 6, e non sono ancora completamente supportate dai browser.

-
- -
-

Nota: il costruttore GeneratorFunction non è un oggetto globale, ma può essere ottenuto dall'istanza della funzione generatrice ( vedi GeneratorFunction per maggiori dettagli ).

-
- -
-

Nota: l'utilizzo del costruttore GeneratorFunction per creare funzioni non è raccomandato, poichè richiede che il corpo della funzione sia scritto come stringa, fatto che può comportare una mancata ottimizzazione da parte di alcuni motori javascript e causare altri problemi.

-
- -

Come tutti gli altri oggetti, un oggetto GeneratorFunction può essere creato utilizzando l'operatore new:

- -
new GeneratorFunction (arg1, arg2, ... argN, functionBody)
-
- -
-
arg1, arg2, ... argN
-
Zero o più nomi da usare come nomi formali di argomenti. Ciascun nome deve essere rappresentato da una stringa testuale che sia conforme alle norme che regolano la definizione di identificatori JavaScript validi, oppure da una lista di stringhe testuali, separate da una virgola; per esempio: "x", "theValue", oppure "a,b".
-
- -
-
functionBody
-
Una stringa testuale che contenga le istruzioni Javascript comprese nella definizione della funzione.
-
- -

Invocare il costruttore Function come funzione ( senza utilizzare l'operatore new ) ha lo stesso effetto di quando lo si invoca come costruttore.

- -

I parametri di una funzione

- -
-

Nota: i parametri di default ed i parametri rest sono tecnologie sperimentali, parte della proposta  ECMAScript 6, e non sono ancora completamente supportati dai browser.

-
- -

Parametri di default

- -

La sintassi per definire i valori di default dei parametri di una funzione permette di inizializzare i parametri formali con valori di default, sempre che non venga passato il valore undefined oppure non venga passato alcun valore. Per maggiori dettagli, vedi default parameters.

- -

I parametri Rest

- -

La sintassi per i parametri rest permette di rappresentare un indefinito numero di argomenti come un array. Per maggiori dettagli, vedi rest parameters.

- -

L'oggetto arguments

- -

È possibile riferirsi agli argomenti di una funzione, all'interno della funzione, utilizzando l'oggetto arguments. Vedi arguments.

- - - -

Definire metodi

- -

Funzioni Getter e setter

- -

È possibile definire metodi getter ( accessor method: metodi per l'accesso al valore di una variabile privata ) e metodi setter ( mutator method: metodi per la modifica del valore di una variabile privata ) per qulasiasi oggetto standard built-in o per qualsiasi oggetto definito dall'utente che supporti l'aggiunta di nuove proprietà. La sintassi da usare per la definizione di metodi getter e setter utilizza la sintassi per la definizione di valori letterali.

- -
-
get
-
-

Lega ( bind ) una proprietà di un oggetto ad una funzione, che verrà invocata ogni volta in cui si cercherà di leggere il valore di quella proprietà.

-
-
set
-
Lega ( bind ) una proprietà di un oggetto alla funzione da invocare ogni volta in cui si cercherà di modificare il valore di quella proprietà.
-
- -

Sintassi per la definizione dei metodi

- -
-

Nota: le definizioni dei metodi sono tecnologie sperimentali, parte della proposta  ECMAScript 6, e non sono ancora completamente supportate dai browser.

-
- -

A partire da ECMAScript 6, è possibile definire propri metodi usando una sintassi più breve, simile alla sintassi usata per i metodi getter e setter. Vedi method definitions per maggiori informazioni.

- -
var obj = {
-  foo() {},
-  bar() {}
-};
- -

Il costruttore Function vs. la dichiarazione di funzione vs. l'espressione di funzione

- -

Compara i seguenti esempi:

- -

Una funzione definita con la dichiarazione di funzione:

- -
function multiply(x, y) {
-   return x * y;
-}
-
- -

Una espressione di funzione di una funzione anonima ( senza nome ), assegnata alla variabile multiply:

- -
var multiply = function(x, y) {
-   return x * y;
-};
-
- -

Una espressione di funzione di una funzione chiamata func_name , assegnata alla variabile multiply:

- -
var multiply = function func_name(x, y) {
-   return x * y;
-};
-
- -

Differenze

- -

Tutti e tre gli esempi fanno più o meno la stessa cosa, con qualche piccola differenza:

- -

C'è una differenza tra il nome di una funzione e la variabile alla quale la funzione viene assegnata. Il nome di una funzione non può essere modificato, mentre la variabile alla quale viene assegnata la funzione può essere riassegnata. Il nome di una funzione può essere utilizzato solo all'interno del corpo della funzione. Tentare di utilizzarlo al di fuori del corpo della funzione genererà un errore ( oppure restituirà undefined se il nome della funzione era stato precedentemente dichiarato con un'istruzione var ). Per esempio:

- -
var y = function x() {};
-alert(x); // throws an error
-
- -

Il nome di una funzione appare anche quando la funzione viene serializzata usando il metodo toString applicato alla funzione.

- -

Dall'altro lato, la variabile alla quale viene assegnata la funzione è limitata solo dal suo scope, la cui inclusione è garantita al momento della dichiarazione di funzione.

- -

Come si può vedere dal quarto esempio, il nome della funzione può essere diverso dal nome della variabile alla quale la funzione viene assegnata. I due nomi non hanno alcuna relazione tra loro. Una dichiarazione di funzione crea anche una variabile con lo stesso nome della funzione. Quindi, diversamente dalle funzioni definite attraverso un'espressione di funzione, le funzioni definite attraverso una dichiarazione di funzione offrono la possibilità di accedere ad esse attraverso il loro nome, almeno all'interno dello scope in cui erano state definite.

- -

Una funzione definita con il costruttore 'new Function' non possiede un nome. Tuttavia, nel motore JavaScript SpiderMonkey, la forma serializzata della funzione mostra il nome "anonymous". Per esempio, il codice alert(new Function()) restituisce:

- -
function anonymous() {
-}
-
- -

Poichè la funzione, in realtà, non ha un nome, anonymous non è una variabile alla quale si potrà accedere, all'interno della funzione. Per esempio, il seguente codice restituirebbe un errore:

- -
var foo = new Function("alert(anonymous);");
-foo();
-
- -

Diversamente da quanto accade con le funzioni definite con espressioni di funzione o con il costruttore Function, una funzione definita con una dichiarazione di funzione può essere usata prima della dichiarazione di funzione stessa. Per esempio:

- -
foo(); // alerts FOO!
-function foo() {
-   alert('FOO!');
-}
-
- -

Una funzione definita da un'espressione di funzione eredita lo scope corrente. Vale a dire, la funzione forma una chiusura. Dall'altro lato, una funzione definita dal costruttore Function non eredita alcuno scope, se non quello globale ( che eredita qualsiasi funzione ).

- -

Le funzioni definite con espressioni di funzione e dichiarazioni di funzione vengono analizzate ( parsed ) solo una volta, mentre quelle definite con il costruttore Function no. Vale a dire, la stringa testuale del corpo della funzione passata al costruttore Function deve essere analizzata ( parsed ) ogni volta in cui viene invocato il costruttore. Sebbene un'espressione di funzione crei ogni volta una chiusura, il corpo della funzione non viene rianalizzato ( reparsed ), così le espressioni di funzione sono ancora più veloci del "new Function(...)". Quindi, il costruttore Function dovrebbe, generalmente, essere evitato dove possibile.

- -

Occorre tenere presente, tuttavia, che le espressioni di funzione e le dichiarazioni di funzione annidate in una funzione generata dall'analisi ( parsing ) di una stringa del costruttore Function non vengono analizzate ( parsed ) continuamente. Per esempio:

- -
var foo = (new Function("var bar = \'FOO!\';\nreturn(function() {\n\talert(bar);\n});"))();
-foo(); // The segment "function() {\n\talert(bar);\n}" of the function body string is not re-parsed.
- -

Una dichiarazione di funzione è molto facilmente ( e spesso, anche non intenzionalmente ) convertita in un'espressione di funzione. Una dichiarazione di funzione cessa di essere tale quando:

- - - -
var x = 0;               // source element
-if (x == 0) {            // source element
-   x = 10;               // not a source element
-   function boo() {}     // not a source element
-}
-function foo() {         // source element
-   var y = 20;           // source element
-   function bar() {}     // source element
-   while (y == 10) {     // source element
-      function blah() {} // not a source element
-      y++;               // not a source element
-   }
-}
-
- -

Examples

- -
// function declaration
-function foo() {}
-
-// function expression
-(function bar() {})
-
-// function expression
-x = function hello() {}
-
-
-if (x) {
-   // function expression
-   function world() {}
-}
-
-
-// function declaration
-function a() {
-   // function declaration
-   function b() {}
-   if (0) {
-      // function expression
-      function c() {}
-   }
-}
-
- -

Definire una funzione in modo condizionato

- -

Le funzioni possono essere definite in modo condizionato, utilizzando sia le istruzioni di funzione ( un'estensione prevista nello standard ECMA-262 Edition 3 ), sia il costruttore Function. Da notare, però, che le  istruzioni di funzione non sono più accettate in ES5 strict mode. Inoltre, questa funzionalità non funziona bene attraverso più browser, quindi sarebbe meglio non farci affidamento.

- -

Nello script seguente, la funzione zero non verrà mai definita e non potrà mai essere invocata, visto che 'if (0)' restituisce sempre false:

- -
if (0) {
-   function zero() {
-      document.writeln("This is zero.");
-   }
-}
-
- -

Se la condizione diventasse 'if (1)', la funzione zero verrebbe definita.

- -

Nota: sebbene questo tipo di funzione sembri una dichiarazione di funzione, in realtà siamo di fronte ad una espressione ( o statement, o istruzione ), poichè la dichiarazione è annidata all'interno di un'altra istruzione. Vedi le differenze tra dichiarazioni di funzione ed espressioni di funzione.

- -

Nota: alcuni motori JavaScript, eslcuso SpiderMonkey, trattano, non correttamente, qualsiasi espressione di funzione in modo da assegnare loro un nome, al momento della definizione. Questo comporterebbe che la funzione zero sarebbe comunque definita, anche nell'eventualità che la condizione if restituisse sempre false. Un modo più sicuro per definire le funzioni in modo condizionato è di definirle come funzioni anonime ed assegnarle, poi, ad una variabile:

- -
if (0) {
-   var zero = function() {
-      document.writeln("This is zero.");
-   }
-}
-
- -

Esempi

- -

Restituire un numero formattato

- -

La seguente funzione restituisce ( return ) una stringa contenente la rappresentazione formattata di un numero, completato ( padded ) con degli zero iniziali.

- -
// This function returns a string padded with leading zeros
-function padZeros(num, totalLen) {
-   var numStr = num.toString();             // Initialize return value as string
-   var numZeros = totalLen - numStr.length; // Calculate no. of zeros
-   for (var i = 1; i <= numZeros; i++) {
-      numStr = "0" + numStr;
-   }
-   return numStr;
-}
-
- -

Queste istruzioni invocano la funzione padZeros.

- -
var result;
-result = padZeros(42,4); // returns "0042"
-result = padZeros(42,2); // returns "42"
-result = padZeros(5,4);  // returns "0005"
-
- -

Determinare l'esistenza di una funzione

- -

È possibile determinare se una funzione esiste, utilizzando l'operatore typeof. Nell'esempio seguente, viene eseguito un test per determinare se l'oggetto window ha una proprietà, che sia una funzione, chiamata noFunc. Se così, la funzione verrà utilizzata; in caso contrario, verrà eseguita una qualsiasi altra azione.

- -
 if ('function' == typeof window.noFunc) {
-   // use noFunc()
- } else {
-   // do something else
- }
-
- -

Da notare che nel test if  viene usato un riferimento a noFunc  — senza usare le parentesi "()" dopo il nome della funzione: in questo modo, la funzione non viene invocata.

- -

Specifications

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
ECMAScript 1st Edition.StandardInitial definition. Implemented in JavaScript 1.0
{{SpecName('ES5.1', '#sec-13', 'Function Definition')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-function-definitions', 'Function definitions')}}{{Spec2('ES6')}}New: Arrow functions, Generator functions, default parameters, rest parameters
{{SpecName('ES6', '#', 'function*')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ES6', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}{{Spec2('ES6')}}Initial definition.
- -

Browser compatibility

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
Generator function39{{CompatGeckoDesktop("26.0")}}{{CompatUnknown}}26{{CompatUnknown}}
Arrow function{{CompatNo}}{{CompatGeckoDesktop("22.0")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
Generator function{{CompatUnknown}}39{{CompatGeckoMobile("26.0")}}{{CompatUnknown}}26{{CompatUnknown}}
Arrow function{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("22.0")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

See also

- - diff --git a/files/it/web/javascript/reference/functions_and_function_scope/set/index.html b/files/it/web/javascript/reference/functions_and_function_scope/set/index.html deleted file mode 100644 index 1af0f1c79d..0000000000 --- a/files/it/web/javascript/reference/functions_and_function_scope/set/index.html +++ /dev/null @@ -1,214 +0,0 @@ ---- -title: setter -slug: Web/JavaScript/Reference/Functions_and_function_scope/set -tags: - - Funzioni - - JavaScript - - setter -translation_of: Web/JavaScript/Reference/Functions/set ---- -
{{jsSidebar("Functions")}}
- -

Il costrutto sintattico set collega una proprietà di un oggetto ad una funzione che viene chiamata quando si ha un tentativo di modifica di quella proprietà.

- -

Sintassi

- -
{set prop(val) { . . . }}
-{set [expression](val) { . . . }}
- -

Parametri

- -
-
prop
-
Il nome della proprietà da collegare alla funzione data.
-
- -
-
val
-
Un alias per la variabile che contiene il valore che si sta cercando di assegnare a prop.
-
expression
-
A partire da ECMAScript 6, è possibile anche usare espressioni per nomi di proprietà computate da collegare alla funzione data.
-
- -

Descrizione

- -

In JavaScript, un setter può essere utilizzato per eseguire una funzione ogniqualvolta una proprietà specificata sta per essere modificata. I setters sono quasi sempre utilizzati insieme ai getters per creare un tipo di pseudo proprietà. Non è possibile avere un setter su una normale proprietà che contiene un valore.

- -

Alcune note da considerare quando si utilizza il costrutto sintattico set:

- -
- -
- -

Un setter può essere eliminato usando l'operatore delete.

- -

Esempi

- -

Definire un setter per nuovi oggetti in inizializzatori di oggetti

- -

Questo snippet di codice definisce una pseudo proprietà current di un oggetto che, una volta che vi si assegna un valore, aggiornerà log con quel valore:

- -
var o = {
-  set current (str) {
-    this.log[this.log.length] = str;
-  },
-  log: []
-}
-
- -

Nota che  current non è definito ed ogni tentativo di accedervi risulterà in un undefined.

- -

Rimuovere un setter con l'operatore delete

- -

Se vuoi rimuovere il setter usato sopra, puoi semplicemente usare delete:

- -
delete o.current;
-
- -

Definire un setter su oggetti pre-esistenti usando defineProperty

- -

Per aggiungere un setter ad un oggetto pre-esistente, usa{{jsxref("Object.defineProperty()")}}.

- -
var o = { a:0 };
-
-Object.defineProperty(o, "b", { set: function (x) { this.a = x / 2; } });
-
-o.b = 10; // Runs the setter, which assigns 10 / 2 (5) to the 'a' property
-console.log(o.a) // 5
- -

Usare il nome di una proprietà computata

- -
-

Nota: Le proprietà computate sono una tecnologia sperimentale, parte dello standard proposto ECMAScript 6, e non sono ancora sufficientemente supportate dai browsers. L'uso di queste proprietà in ambienti che non le supportano produrrà un errore di sintassi.

-
- -
var expr = "foo";
-
-var obj = {
-  baz: "bar",
-  set [expr](v) { this.baz = v; }
-};
-
-console.log(obj.baz); // "bar"
-obj.foo = "baz";      // run the setter
-console.log(obj.baz); // "baz"
-
- -

Specifiche

- - - - - - - - - - - - - - - - - - - - - - - - -
SpecificaStatusCommento
{{SpecName('ES5.1', '#sec-11.1.5', 'Object Initializer')}}{{Spec2('ES5.1')}}Definizione iniziale.
{{SpecName('ES6', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ES6')}}Aggiunti i nomi di proprietà computate.
{{SpecName('ESDraft', '#sec-method-definitions', 'Method definitions')}}{{Spec2('ESDraft')}}
- -

Compatibilità dei browsers

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
CaratteristicaChromeFirefox (Gecko)Internet ExplorerOperaSafari
Supporto base{{CompatChrome(1)}}{{ CompatGeckoDesktop("1.8.1") }}{{ CompatIE(9) }}9.53
Nomi di proprietà computate{{CompatNo}}{{ CompatGeckoDesktop("34") }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CaratteristicaAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Supporto base{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{ CompatGeckoMobile("1.8.1") }}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
Nomi di proprietà computate{{CompatNo}}{{CompatNo}}{{ CompatGeckoMobile("34.0") }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

Note specifiche per SpiderMonkey

- - - -

Guarda anche

- - diff --git a/files/it/web/javascript/reference/global_objects/array/prototype/index.html b/files/it/web/javascript/reference/global_objects/array/prototype/index.html deleted file mode 100644 index d4989792a8..0000000000 --- a/files/it/web/javascript/reference/global_objects/array/prototype/index.html +++ /dev/null @@ -1,203 +0,0 @@ ---- -title: Array.prototype -slug: Web/JavaScript/Reference/Global_Objects/Array/prototype -translation_of: Web/JavaScript/Reference/Global_Objects/Array/prototype ---- -
{{JSRef}}
- -

La proprietà Array.prototype rappresenta il prototipo per il costruttore {{jsxref("Array")}} .

- -
{{js_property_attributes(0, 0, 0)}}
- -

Descrizione

- -

Le istanze {{jsxref("Array")}} ereditano da Array.prototype. Come con gli altri costruttori, si può cambiare il prototipo propagando i cambiamenti su tutte le sue istanze.

- -

Piccola curiosità: Array.prototype è un {{jsxref("Array")}}:

- -
Array.isArray(Array.prototype); // true
-
- -

Proprietà

- -
-
Array.prototype.constructor
-
Restituisce il costruttore.
-
{{jsxref("Array.prototype.length")}}
-
Restituisce il numero di elementi in un array.
-
- -

Metodi

- -

Metodi mutator

- -

Questi metodi modificano l'array:

- -
-
{{jsxref("Array.prototype.copyWithin()")}} {{experimental_inline}}
-
Copia una sequenza di elementi dell'array all'interno dello stesso.
-
{{jsxref("Array.prototype.fill()")}} {{experimental_inline}}
-
Riempie le posizioni dell'array contenute tra 2 indici con un valore fisso.
-
{{jsxref("Array.prototype.pop()")}}
-
Rimuove e restituisce l'ultimo elemento dell'array.
-
{{jsxref("Array.prototype.push()")}}
-
Accoda uno o più elementi all'array e restituisce la lunghezza aggiornata dello stesso.
-
{{jsxref("Array.prototype.reverse()")}}
-
Inverte l'ordine delle posizioni degli elementi all'interno dell'array.
-
{{jsxref("Array.prototype.shift()")}}
-
Rimuove e resistuisce il primo elemento di un array.
-
{{jsxref("Array.prototype.sort()")}}
-
Ordina gli elementi di un array all'interno di esso e restituisce l'array.
-
{{jsxref("Array.prototype.splice()")}}
-
Aggiunge e/o rimuove elementi da un array.
-
{{jsxref("Array.prototype.unshift()")}}
-
Aggiunge uno o più elementi all'inizio di un array e restituisce la lunghezza aggiornata dello stesso.
-
- -

Metodi accessor

- -

Questi metodi non modificano l'array e ne restituiscono una sua rappresentazione.

- -
-
{{jsxref("Array.prototype.concat()")}}
-
Restituisce un nuovo array costituito dall'array stesso insieme ad altri array/valori.
-
{{jsxref("Array.prototype.includes()")}} {{experimental_inline}}
-
Restituisce true se l'array contiene un certo elemento, false altrimenti.
-
{{jsxref("Array.prototype.join()")}}
-
Resituisce i valori dell'array come stringa.
-
{{jsxref("Array.prototype.slice()")}}
-
Restituisce un nuovo array cosituito da elementi dell'array originale.
-
{{jsxref("Array.prototype.toSource()")}} {{non-standard_inline}}
-
Returns an array literal representing the specified array; you can use this value to create a new array. Overrides the {{jsxref("Object.prototype.toSource()")}} method.
-
{{jsxref("Array.prototype.toString()")}}
-
Returns a string representing the array and its elements. Overrides the {{jsxref("Object.prototype.toString()")}} method.
-
{{jsxref("Array.prototype.toLocaleString()")}}
-
Returns a localized string representing the array and its elements. Overrides the {{jsxref("Object.prototype.toLocaleString()")}} method.
-
{{jsxref("Array.prototype.indexOf()")}}
-
Returns the first (least) index of an element within the array equal to the specified value, or -1 if none is found.
-
{{jsxref("Array.prototype.lastIndexOf()")}}
-
Returns the last (greatest) index of an element within the array equal to the specified value, or -1 if none is found.
-
- -

Iteration methods

- -

Several methods take as arguments functions to be called back while processing the array. When these methods are called, the length of the array is sampled, and any element added beyond this length from within the callback is not visited. Other changes to the array (setting the value of or deleting an element) may affect the results of the operation if the method visits the changed element afterwards. While the specific behavior of these methods in such cases is well-defined, you should not rely upon it so as not to confuse others who might read your code. If you must mutate the array, copy into a new array instead.

- -
-
{{jsxref("Array.prototype.forEach()")}}
-
Calls a function for each element in the array.
-
{{jsxref("Array.prototype.entries()")}} {{experimental_inline}}
-
Returns a new Array Iterator object that contains the key/value pairs for each index in the array.
-
{{jsxref("Array.prototype.every()")}}
-
Returns true if every element in this array satisfies the provided testing function.
-
{{jsxref("Array.prototype.some()")}}
-
Returns true if at least one element in this array satisfies the provided testing function.
-
{{jsxref("Array.prototype.filter()")}}
-
Creates a new array with all of the elements of this array for which the provided filtering function returns true.
-
{{jsxref("Array.prototype.find()")}} {{experimental_inline}}
-
Returns the found value in the array, if an element in the array satisfies the provided testing function or undefined if not found.
-
{{jsxref("Array.prototype.findIndex()")}} {{experimental_inline}}
-
Returns the found index in the array, if an element in the array satisfies the provided testing function or -1 if not found.
-
{{jsxref("Array.prototype.keys()")}} {{experimental_inline}}
-
Returns a new Array Iterator that contains the keys for each index in the array.
-
{{jsxref("Array.prototype.map()")}}
-
Creates a new array with the results of calling a provided function on every element in this array.
-
{{jsxref("Array.prototype.reduce()")}}
-
Apply a function against an accumulator and each value of the array (from left-to-right) as to reduce it to a single value.
-
{{jsxref("Array.prototype.reduceRight()")}}
-
Apply a function against an accumulator and each value of the array (from right-to-left) as to reduce it to a single value.
-
{{jsxref("Array.prototype.values()")}} {{experimental_inline}}
-
Returns a new Array Iterator object that contains the values for each index in the array.
-
{{jsxref("Array.prototype.@@iterator()", "Array.prototype[@@iterator]()")}} {{experimental_inline}}
-
Returns a new Array Iterator object that contains the values for each index in the array.
-
- -

Generic methods

- -

Many methods on the JavaScript Array object are designed to be generally applied to all objects which “look like” Arrays. That is, they can be used on any object which has a length property, and which can usefully be accessed using numeric property names (as with array[5] indexing). TODO: give examples with Array.prototype.forEach.call, and adding the method to an object like {{jsxref("Global_Objects/JavaArray", "JavaArray")}} or {{jsxref("Global_Objects/String", "String")}}. Some methods, such as {{jsxref("Array.join", "join")}}, only read the length and numeric properties of the object they are called on. Others, like {{jsxref("Array.reverse", "reverse")}}, require that the object's numeric properties and length be mutable; these methods can therefore not be called on objects like {{jsxref("String")}}, which does not permit its length property or synthesized numeric properties to be set.

- -

Specifications

- - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-15.4.3.1', 'Array.prototype')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-array.prototype', 'Array.prototype')}}{{Spec2('ES6')}} 
- -

Browser compatibility

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -

See also

- - diff --git a/files/it/web/javascript/reference/global_objects/object/prototype/index.html b/files/it/web/javascript/reference/global_objects/object/prototype/index.html deleted file mode 100644 index 568165d0be..0000000000 --- a/files/it/web/javascript/reference/global_objects/object/prototype/index.html +++ /dev/null @@ -1,215 +0,0 @@ ---- -title: Object.prototype -slug: Web/JavaScript/Reference/Global_Objects/Object/prototype -translation_of: Web/JavaScript/Reference/Global_Objects/Object -translation_of_original: Web/JavaScript/Reference/Global_Objects/Object/prototype ---- -
{{JSRef("Global_Objects", "Object")}}
- -

Sommario

- -

La proprietà Object.prototype rappresenta l'oggetto prototipo di {{jsxref("Global_Objects/Object", "Object")}}.

- -

{{js_property_attributes(0, 0, 0)}}

- -

Descrizione

- -

In JavaScript, tutti gli oggetti sono discendenti di {{jsxref("Global_Objects/Object", "Object")}}; tutti gli oggetti ereditano metodi e proprietà di Object.prototype (tranne nel caso l'oggetto abbia il prototipo uguale a {{jsxref("Global_Objects/null", "null")}}, quindi creati con il metodo {{jsxref("Object.create", "Object.create(null)")}}), anche se questi possono essere sovrascritti. Per esempio, i prototipi degli altri costruttori sovrascrivono la proprietà constructor e forniscono un loro metodo {{jsxref("Object.prototype.toString", "toString()")}}. I cambiamenti al prototipo di Object vengono estesi a tutti gli oggetti, eccetto quelli che sovrascrivono le proprietà e i metodi cambiati.

- -

Proprietà

- -
-
{{jsxref("Object.prototype.constructor")}}
-
Specifica la funzione che ha creato l'oggetto a partire dal prototipo.
-
{{jsxref("Object.prototype.__proto__")}} {{non-standard_inline}}
-
È un riferimento all'oggetto usato come prototipo quando l'oggetto è stato istanziato.
-
{{jsxref("Object.prototype.__noSuchMethod__")}} {{non-standard_inline}}
-
Permette di definire una funzione che venga chiamata quando viene chiamato un metodo non definito.
-
{{jsxref("Object.prototype.__count__")}} {{obsolete_inline}}
-
Rappresenta il numero di proprietà persenti in un oggetto, ma è stato rimosso.
-
{{jsxref("Object.prototype.__parent__")}} {{obsolete_inline}}
-
Rappresenta il contesto di un oggetto, ma è stato rimosso.
-
- -

Metodi

- -
-
{{jsxref("Object.prototype.__defineGetter__()")}} {{non-standard_inline}} {{deprecated_inline}}
-
Associa una funzione a una proprietà di un oggetto. Quando si tenta di leggere il valore di tale proprietà, viene eseguita la funzione e restituito il valore che restituisce.
-
{{jsxref("Object.prototype.__defineSetter__()")}} {{non-standard_inline}} {{deprecated_inline}}
-
Associa una funzione a una proprietà di un oggetto. Quando si tenta di cambiare il valore di tale proprietà, viene eseguita la funzione.
-
{{jsxref("Object.prototype.__lookupGetter__()")}} {{non-standard_inline}} {{deprecated_inline}}
-
Restituisce la funzione definita tramite {{jsxref("Object.prototype.defineGetter", "__defineGetter__()")}}.
-
{{jsxref("Object.prototype.__lookupSetter__()")}} {{non-standard_inline}} {{deprecated_inline}}
-
Restituisce la funzione definita tramite {{jsxref("Object.prototype.defineSetter", "__defineSetter__()")}}.
-
{{jsxref("Object.prototype.hasOwnProperty()")}}
-
Determina se l'oggetto contiene direttamente una proprietà (non ereditata tramite il prototipo).
-
{{jsxref("Object.prototype.isPrototypeOf()")}}
-
Determina se un oggetto fa parte della catena dei prototipi dell'oggetto sul quale è richiamato questo metodo.
-
{{jsxref("Object.prototype.propertyIsEnumerable()")}}
-
Determina se l'attributo DontEnum di ECMAScript interno è presente.
-
{{jsxref("Object.prototype.toSource()")}} {{non-standard_inline}}
-
Restituisce una stringa contenente il codice sorgente di un oggetto rappresentante l'oggetto sul quale questo metodo viene richiamato; puoi usare questo valore per creare un nuovo oggetto.
-
{{jsxref("Object.prototype.toLocaleString()")}}
-
Richiama {{jsxref("Object.prototype.toString", "toString()")}}.
-
{{jsxref("Object.prototype.toString()")}}
-
Restituisce la rappresentazione dell'oggetto sotto forma di stringa.
-
{{jsxref("Object.prototype.unwatch()")}} {{non-standard_inline}}
-
Termina di osservare i cambiamenti di una proprietà dell'oggetto.
-
{{jsxref("Object.prototype.valueOf()")}}
-
Ritorna il valore primitivo dell'oggetto.
-
{{jsxref("Object.prototype.watch()")}} {{non-standard_inline}}
-
Inizia a osservare i cambiamenti di una proprietà di un oggetto.
-
{{jsxref("Object.prototype.eval()")}} {{obsolete_inline}}
-
Esegue una stringa di codice JavaScript nel contesto dell'oggetto, ma è stato rimosso.
-
- -

Esempi

- -

Siccome in JavaScript gli oggetti non sono sub-classabili in modo "standard", il prototipo è una soluzione utile per creare un oggetto che funzioni da "classe di base" che contenga dei metodi comuni a più oggetti. Per esempio:

- -
var Persona = function() {
-  this.saParlare = true;
-};
-
-Persona.prototype.saluta = function() {
-  if (this.saParlare) {
-    console.log('Ciao, mi chiamo ' + this.nome);
-  }
-};
-
-var Dipendente = function(nome, titolo) {
-  Persona.call(this);
-  this.nome = nome;
-  this.titolo = titolo;
-};
-
-Dipendente.prototype = Object.create(Persona.prototype);
-Dipendente.prototype.constructor = Dipendente;
-
-Dipendente.prototype.saluta = function() {
-  if (this.saParlare) {
-    console.log('Ciao mi chiamo ' + this.nome + ' e lavoro come ' + this.titolo);
-  }
-};
-
-var Cliente = function(nome) {
-  Persona.call(this);
-  this.nome = nome;
-};
-
-Cliente.prototype = Object.create(Persona.prototype);
-Cliente.prototype.constructor = Cliente;
-
-var Mimo = function(nome) {
-  Persona.call(this);
-  this.nome = nome;
-  this.saParlare = false;
-};
-
-Mimo.prototype = Object.create(Persona.prototype);
-Mimo.prototype.constructor = Mimo;
-
-var bob = new Dipendente('Bob', 'Architetto');
-var joe = new Cliente('Joe');
-var rg = new Dipendente('Red Green', 'Tuttofare');
-var mike = new Cliente('Mike');
-var mime = new Mimo('Mimo');
-bob.saluta();
-joe.saluta();
-rg.saluta();
-mike.saluta();
-mime.saluta();
-
- -

Stamperà:

- -
Ciao, mi chiamo Bob e lavoro come Architetto
-Ciao, mi chiamo Joe
-Ciao, mi chiamo Red Green, e lavoro come Tuttofare
-Ciao, mi chiamo Mike
- -

Specifiche

- - - - - - - - - - - - - - - - - - - - - - - - -
SpecificaStatoCommenti
ECMAScript 1st Edition. Implemented in JavaScript 1.0.StandardDefinizione iniziale.
{{SpecName('ES5.1', '#sec-15.2.3.1', 'Object.prototype')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-object.prototype', 'Object.prototype')}}{{Spec2('ES6')}} 
- -

Compatibilità con i browser

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FunzionalitàChromeFirefox (Gecko)Internet ExplorerOperaSafari
Supporto di base{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FunzionalitàAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Supporto di base{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -

See also

- - diff --git a/files/it/web/javascript/reference/global_objects/proxy/handler/apply/index.html b/files/it/web/javascript/reference/global_objects/proxy/handler/apply/index.html deleted file mode 100644 index f803b41255..0000000000 --- a/files/it/web/javascript/reference/global_objects/proxy/handler/apply/index.html +++ /dev/null @@ -1,119 +0,0 @@ ---- -title: handler.apply() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply -tags: - - ECMAScript 2015 - - JavaScript - - Proxy - - metodo -translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/apply ---- -
{{JSRef}}
- -

Il metodo handler.apply() costituisce una trap per una chiamata a funzione.

- -
{{EmbedInteractiveExample("pages/js/proxyhandler-apply.html", "taller")}}
- - - -

Sintassi

- -
var p = new Proxy(target, {
-  apply: function(target, thisArg, argumentsList) {
-  }
-});
-
- -

Parametri

- -

I seguenti parametri vengono passati al metodo apply. this è legato all'handler.

- -
-
target
-
L'oggetto target.
-
thisArg
-
Il valore di this relativo alla chiamata.
-
argumentsList
-
La lista degli argomenti della chiamata.
-
- -

Valore di ritorno

- -

Il metodo apply può restituire qualsiasi valore.

- -

Descrizione

- -

Il metodo handler.apply è una trap per le chiamate a funzione.

- -

Operazioni intercettate

- -

Questa trap può intercettare le seguenti operazioni:

- - - -

Invarianti

- -

Se le seguenti invarianti non sono rispettate il proxy emetterà un TypeError:

- - - -

Esempi

- -

Il codice seguente intercetta una chiamata a funzione.

- -
var p = new Proxy(function() {}, {
-  apply: function(target, thisArg, argumentsList) {
-    console.log('chiamato con: ' + argumentsList.join(', '));
-    return argumentsList[0] + argumentsList[1] + argumentsList[2];
-  }
-});
-
-console.log(p(1, 2, 3)); // "chiamato con: 1, 2, 3"
-                         // 6
-
- -

Specifiche

- - - - - - - - - - - - - - - - - - - -
SpecificaStatoCommenti
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist', '[[Call]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist', '[[Call]]')}}{{Spec2('ESDraft')}} 
- -

Compatibilità browser

- -
- - -

{{Compat("javascript.builtins.Proxy.handler.apply")}}

-
- -

Vedi anche

- - diff --git a/files/it/web/javascript/reference/global_objects/proxy/handler/index.html b/files/it/web/javascript/reference/global_objects/proxy/handler/index.html deleted file mode 100644 index 2be6abb116..0000000000 --- a/files/it/web/javascript/reference/global_objects/proxy/handler/index.html +++ /dev/null @@ -1,84 +0,0 @@ ---- -title: Proxy handler -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler -tags: - - ECMAScript 2015 - - JavaScript - - NeedsTranslation - - Proxy - - TopicStub -translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy -translation_of_original: Web/JavaScript/Reference/Global_Objects/Proxy/handler ---- -
{{JSRef}}
- -

The proxy's handler object is a placeholder object which contains traps for {{jsxref("Proxy", "proxies", "", 1)}}.

- -

Methods

- -

All traps are optional. If a trap has not been defined, the default behavior is to forward the operation to the target.

- -
-
{{jsxref("Global_Objects/Proxy/handler/getPrototypeOf", "handler.getPrototypeOf()")}}
-
A trap for {{jsxref("Object.getPrototypeOf")}}.
-
{{jsxref("Global_Objects/Proxy/handler/setPrototypeOf", "handler.setPrototypeOf()")}}
-
A trap for {{jsxref("Object.setPrototypeOf")}}.
-
{{jsxref("Global_Objects/Proxy/handler/isExtensible", "handler.isExtensible()")}}
-
A trap for {{jsxref("Object.isExtensible")}}.
-
{{jsxref("Global_Objects/Proxy/handler/preventExtensions", "handler.preventExtensions()")}}
-
A trap for {{jsxref("Object.preventExtensions")}}.
-
{{jsxref("Global_Objects/Proxy/handler/getOwnPropertyDescriptor", "handler.getOwnPropertyDescriptor()")}}
-
A trap for {{jsxref("Object.getOwnPropertyDescriptor")}}.
-
{{jsxref("Global_Objects/Proxy/handler/defineProperty", "handler.defineProperty()")}}
-
A trap for {{jsxref("Object.defineProperty")}}.
-
{{jsxref("Global_Objects/Proxy/handler/has", "handler.has()")}}
-
A trap for the {{jsxref("Operators/in", "in")}} operator.
-
{{jsxref("Global_Objects/Proxy/handler/get", "handler.get()")}}
-
A trap for getting property values.
-
{{jsxref("Global_Objects/Proxy/handler/set", "handler.set()")}}
-
A trap for setting property values.
-
{{jsxref("Global_Objects/Proxy/handler/deleteProperty", "handler.deleteProperty()")}}
-
A trap for the {{jsxref("Operators/delete", "delete")}} operator.
-
{{jsxref("Global_Objects/Proxy/handler/ownKeys", "handler.ownKeys()")}}
-
A trap for {{jsxref("Object.getOwnPropertyNames")}} and {{jsxref("Object.getOwnPropertySymbols")}}.
-
{{jsxref("Global_Objects/Proxy/handler/apply", "handler.apply()")}}
-
A trap for a function call.
-
{{jsxref("Global_Objects/Proxy/handler/construct", "handler.construct()")}}
-
A trap for the {{jsxref("Operators/new", "new")}} operator.
-
- -

Some non-standard traps are obsolete and have been removed.

- -

Specifications

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots', 'Proxy Object Internal Methods and Internal Slots')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots', 'Proxy Object Internal Methods and Internal Slots')}}{{Spec2('ESDraft')}}The enumerate handler has been removed.
- -

Browser compatibility

- - - -

{{Compat("javascript.builtins.Proxy.handler")}}

- -

See also

- - diff --git a/files/it/web/javascript/reference/global_objects/proxy/proxy/apply/index.html b/files/it/web/javascript/reference/global_objects/proxy/proxy/apply/index.html new file mode 100644 index 0000000000..f803b41255 --- /dev/null +++ b/files/it/web/javascript/reference/global_objects/proxy/proxy/apply/index.html @@ -0,0 +1,119 @@ +--- +title: handler.apply() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply +tags: + - ECMAScript 2015 + - JavaScript + - Proxy + - metodo +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/apply +--- +
{{JSRef}}
+ +

Il metodo handler.apply() costituisce una trap per una chiamata a funzione.

+ +
{{EmbedInteractiveExample("pages/js/proxyhandler-apply.html", "taller")}}
+ + + +

Sintassi

+ +
var p = new Proxy(target, {
+  apply: function(target, thisArg, argumentsList) {
+  }
+});
+
+ +

Parametri

+ +

I seguenti parametri vengono passati al metodo apply. this è legato all'handler.

+ +
+
target
+
L'oggetto target.
+
thisArg
+
Il valore di this relativo alla chiamata.
+
argumentsList
+
La lista degli argomenti della chiamata.
+
+ +

Valore di ritorno

+ +

Il metodo apply può restituire qualsiasi valore.

+ +

Descrizione

+ +

Il metodo handler.apply è una trap per le chiamate a funzione.

+ +

Operazioni intercettate

+ +

Questa trap può intercettare le seguenti operazioni:

+ + + +

Invarianti

+ +

Se le seguenti invarianti non sono rispettate il proxy emetterà un TypeError:

+ + + +

Esempi

+ +

Il codice seguente intercetta una chiamata a funzione.

+ +
var p = new Proxy(function() {}, {
+  apply: function(target, thisArg, argumentsList) {
+    console.log('chiamato con: ' + argumentsList.join(', '));
+    return argumentsList[0] + argumentsList[1] + argumentsList[2];
+  }
+});
+
+console.log(p(1, 2, 3)); // "chiamato con: 1, 2, 3"
+                         // 6
+
+ +

Specifiche

+ + + + + + + + + + + + + + + + + + + +
SpecificaStatoCommenti
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist', '[[Call]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist', '[[Call]]')}}{{Spec2('ESDraft')}} 
+ +

Compatibilità browser

+ +
+ + +

{{Compat("javascript.builtins.Proxy.handler.apply")}}

+
+ +

Vedi anche

+ + diff --git a/files/it/web/javascript/reference/global_objects/proxy/proxy/index.html b/files/it/web/javascript/reference/global_objects/proxy/proxy/index.html new file mode 100644 index 0000000000..2be6abb116 --- /dev/null +++ b/files/it/web/javascript/reference/global_objects/proxy/proxy/index.html @@ -0,0 +1,84 @@ +--- +title: Proxy handler +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler +tags: + - ECMAScript 2015 + - JavaScript + - NeedsTranslation + - Proxy + - TopicStub +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy +translation_of_original: Web/JavaScript/Reference/Global_Objects/Proxy/handler +--- +
{{JSRef}}
+ +

The proxy's handler object is a placeholder object which contains traps for {{jsxref("Proxy", "proxies", "", 1)}}.

+ +

Methods

+ +

All traps are optional. If a trap has not been defined, the default behavior is to forward the operation to the target.

+ +
+
{{jsxref("Global_Objects/Proxy/handler/getPrototypeOf", "handler.getPrototypeOf()")}}
+
A trap for {{jsxref("Object.getPrototypeOf")}}.
+
{{jsxref("Global_Objects/Proxy/handler/setPrototypeOf", "handler.setPrototypeOf()")}}
+
A trap for {{jsxref("Object.setPrototypeOf")}}.
+
{{jsxref("Global_Objects/Proxy/handler/isExtensible", "handler.isExtensible()")}}
+
A trap for {{jsxref("Object.isExtensible")}}.
+
{{jsxref("Global_Objects/Proxy/handler/preventExtensions", "handler.preventExtensions()")}}
+
A trap for {{jsxref("Object.preventExtensions")}}.
+
{{jsxref("Global_Objects/Proxy/handler/getOwnPropertyDescriptor", "handler.getOwnPropertyDescriptor()")}}
+
A trap for {{jsxref("Object.getOwnPropertyDescriptor")}}.
+
{{jsxref("Global_Objects/Proxy/handler/defineProperty", "handler.defineProperty()")}}
+
A trap for {{jsxref("Object.defineProperty")}}.
+
{{jsxref("Global_Objects/Proxy/handler/has", "handler.has()")}}
+
A trap for the {{jsxref("Operators/in", "in")}} operator.
+
{{jsxref("Global_Objects/Proxy/handler/get", "handler.get()")}}
+
A trap for getting property values.
+
{{jsxref("Global_Objects/Proxy/handler/set", "handler.set()")}}
+
A trap for setting property values.
+
{{jsxref("Global_Objects/Proxy/handler/deleteProperty", "handler.deleteProperty()")}}
+
A trap for the {{jsxref("Operators/delete", "delete")}} operator.
+
{{jsxref("Global_Objects/Proxy/handler/ownKeys", "handler.ownKeys()")}}
+
A trap for {{jsxref("Object.getOwnPropertyNames")}} and {{jsxref("Object.getOwnPropertySymbols")}}.
+
{{jsxref("Global_Objects/Proxy/handler/apply", "handler.apply()")}}
+
A trap for a function call.
+
{{jsxref("Global_Objects/Proxy/handler/construct", "handler.construct()")}}
+
A trap for the {{jsxref("Operators/new", "new")}} operator.
+
+ +

Some non-standard traps are obsolete and have been removed.

+ +

Specifications

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots', 'Proxy Object Internal Methods and Internal Slots')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots', 'Proxy Object Internal Methods and Internal Slots')}}{{Spec2('ESDraft')}}The enumerate handler has been removed.
+ +

Browser compatibility

+ + + +

{{Compat("javascript.builtins.Proxy.handler")}}

+ +

See also

+ + diff --git a/files/it/web/javascript/reference/global_objects/proxy/revocabile/index.html b/files/it/web/javascript/reference/global_objects/proxy/revocabile/index.html deleted file mode 100644 index bf87d7e3e7..0000000000 --- a/files/it/web/javascript/reference/global_objects/proxy/revocabile/index.html +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: Proxy.revocable() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/revocabile -translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/revocable ---- -
{{JSRef}}
- -

Il metodo Proxy.revocable() è usato per creare un oggetto {{jsxref("Proxy")}} revocabile.

- -

Sintassi

- -
Proxy.revocable(target, handler);
-
- -

Parametri

- -
{{ Page("it/docs/Web/JavaScript/Reference/Global_Objects/Proxy", "Parametri") }}
- -

Valore restituito

- -

Un nuovo oggetto Proxy revocabile.

- -

Descrizione

- -

Un Proxy revocabile è un oggetto con le seguenti due proprietà {proxy: proxy, revoke: revoke}.

- -
-
proxy
-
L'oggetto Proxy creato con new Proxy(target, handler).
-
revoke
-
Una funzione che non richiede argomenti per disattivare il proxy.
-
- -

Se la funzione revoke() viene invocata, il proxy diventa inutilizzabile: se si tenta di farne uso si otterrà un {{jsxref("TypeError")}}. Una volta che il proxy è revocato rimarrà in questo stato e potrà essere eliminato dal garbage collector. Successive invocazioni di revoke() non avranno effetto.

- -

Esempi

- -
var revocable = Proxy.revocable({}, {
-  get: function(target, name) {
-    return "[[" + name + "]]";
-  }
-});
-var proxy = revocable.proxy;
-console.log(proxy.foo); // "[[foo]]"
-
-revocable.revoke();
-
-console.log(proxy.foo); // viene sollevato un TypeError
-proxy.foo = 1           // viene sollevato un TypeError
-delete proxy.foo;       // viene sollevato un TypeError
-typeof proxy            // "object", typeof non innesca nessuna trappola
-
- -

Specifiche

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy.revocable', 'Proxy Revocation Functions')}}{{Spec2('ES2015')}}Definizione iniziale.
{{SpecName('ESDraft', '#sec-proxy.revocable', 'Proxy Revocation Functions')}}{{Spec2('ESDraft')}} 
- -

Compatibilità tra Browser

- - - -

{{Compat("javascript.builtins.Proxy.revocable")}}

- -

Vedi anche

- - diff --git a/files/it/web/javascript/reference/global_objects/proxy/revocable/index.html b/files/it/web/javascript/reference/global_objects/proxy/revocable/index.html new file mode 100644 index 0000000000..bf87d7e3e7 --- /dev/null +++ b/files/it/web/javascript/reference/global_objects/proxy/revocable/index.html @@ -0,0 +1,86 @@ +--- +title: Proxy.revocable() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/revocabile +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/revocable +--- +
{{JSRef}}
+ +

Il metodo Proxy.revocable() è usato per creare un oggetto {{jsxref("Proxy")}} revocabile.

+ +

Sintassi

+ +
Proxy.revocable(target, handler);
+
+ +

Parametri

+ +
{{ Page("it/docs/Web/JavaScript/Reference/Global_Objects/Proxy", "Parametri") }}
+ +

Valore restituito

+ +

Un nuovo oggetto Proxy revocabile.

+ +

Descrizione

+ +

Un Proxy revocabile è un oggetto con le seguenti due proprietà {proxy: proxy, revoke: revoke}.

+ +
+
proxy
+
L'oggetto Proxy creato con new Proxy(target, handler).
+
revoke
+
Una funzione che non richiede argomenti per disattivare il proxy.
+
+ +

Se la funzione revoke() viene invocata, il proxy diventa inutilizzabile: se si tenta di farne uso si otterrà un {{jsxref("TypeError")}}. Una volta che il proxy è revocato rimarrà in questo stato e potrà essere eliminato dal garbage collector. Successive invocazioni di revoke() non avranno effetto.

+ +

Esempi

+ +
var revocable = Proxy.revocable({}, {
+  get: function(target, name) {
+    return "[[" + name + "]]";
+  }
+});
+var proxy = revocable.proxy;
+console.log(proxy.foo); // "[[foo]]"
+
+revocable.revoke();
+
+console.log(proxy.foo); // viene sollevato un TypeError
+proxy.foo = 1           // viene sollevato un TypeError
+delete proxy.foo;       // viene sollevato un TypeError
+typeof proxy            // "object", typeof non innesca nessuna trappola
+
+ +

Specifiche

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy.revocable', 'Proxy Revocation Functions')}}{{Spec2('ES2015')}}Definizione iniziale.
{{SpecName('ESDraft', '#sec-proxy.revocable', 'Proxy Revocation Functions')}}{{Spec2('ESDraft')}} 
+ +

Compatibilità tra Browser

+ + + +

{{Compat("javascript.builtins.Proxy.revocable")}}

+ +

Vedi anche

+ + diff --git a/files/it/web/javascript/reference/global_objects/string/prototype/index.html b/files/it/web/javascript/reference/global_objects/string/prototype/index.html deleted file mode 100644 index c83cec2a54..0000000000 --- a/files/it/web/javascript/reference/global_objects/string/prototype/index.html +++ /dev/null @@ -1,179 +0,0 @@ ---- -title: String.prototype -slug: Web/JavaScript/Reference/Global_Objects/String/prototype -translation_of: Web/JavaScript/Reference/Global_Objects/String -translation_of_original: Web/JavaScript/Reference/Global_Objects/String/prototype ---- -
{{JSRef}}
- -

La proprietà String.prototyperappresenta l'oggetto prototipo {{jsxref("String")}}.

- -
{{js_property_attributes(0, 0, 0)}}
- -

Description

- -

Tutte le istanze {{jsxref("String")}} ereditano da String.prototype . Le modifiche all'oggetto prototipo String vengono propagate a tutte le istanze {{jsxref("String")}}.

- -

Properties

- -
-
String.prototype.constructor
-
Specifica la funzione che crea il prototipo di un oggetto.
-
{{jsxref("String.prototype.length")}}
-
Riflette la lunghezza della stringa.
-
N
-
Utilizzato per accedere al carattere in N posizione in cui N è un numero intero positivo compreso tra 0 e uno inferiore al valore della {{jsxref("String.length", "length")}}. Queste proprietà sono di sola lettura.
-
- -

Metodi

- -

Metodi non correlati HTML

- -
-
{{jsxref("String.prototype.charAt()")}}
-
Restituisce il carattere (esattamente un'unità di codice UTF-16) all'indice specificato
-
{{jsxref("String.prototype.charCodeAt()")}}
-
Restituisce un numero che corrisponde al valore dell'unità di codice UTF-16 nell'indice specificato.
-
{{jsxref("String.prototype.codePointAt()")}}
-
Restituisce un numero intero non negativo Numero che è il valore del punto di codice codificato UTF-16 che inizia con l'indice specificato.
-
{{jsxref("String.prototype.concat()")}}
-
Combina il testo di due stringhe e restituisce una nuova stringa.
-
{{jsxref("String.prototype.includes()")}}
-
Determina se una stringa può essere trovata all'interno di un'altra stringa.
-
{{jsxref("String.prototype.endsWith()")}}
-
Determina se una stringa termina con i caratteri di un'altra stringa.
-
{{jsxref("String.prototype.indexOf()")}}
-
Restituisce l'indice all'interno dell'oggetto {{jsxref("String")}} chiamante della prima occorrenza del valore specificato o -1 se non trovato.
-
{{jsxref("String.prototype.lastIndexOf()")}}
-
Restituisce l'indice all'interno dell'oggetto {{jsxref("String")}} chiamante della prima occorrenza del valore specificato o -1 se non trovato.
-
{{jsxref("String.prototype.localeCompare()")}}
-
Restituisce un numero che indica se una stringa di riferimento viene prima o dopo o è uguale alla stringa specificata in ordine di ordinamento.
-
{{jsxref("String.prototype.match()")}}
-
Utilizzato per abbinare un'espressione regolare a una stringa.
-
{{jsxref("String.prototype.normalize()")}}
-
Restituisce il modulo di normalizzazione Unicode del valore della stringa chiamante.
-
{{jsxref("String.prototype.padEnd()")}}
-
Riempie la stringa corrente dalla fine con una determinata stringa per creare una nuova stringa di una determinata lunghezza.
-
{{jsxref("String.prototype.padStart()")}}
-
Riempie la stringa corrente dall'inizio con una determinata stringa per creare una nuova stringa da una determinata lunghezza.
-
{{jsxref("String.prototype.quote()")}} {{obsolete_inline}}
-
Avvolge la stringa tra virgolette (""").
-
{{jsxref("String.prototype.repeat()")}}
-
Restituisce una stringa composta da elementi dell'oggetto ripetuti i tempi indicati.
-
{{jsxref("String.prototype.replace()")}}
-
Utilizzato per trovare una corrispondenza tra un'espressione regolare e una stringa e per sostituire la sottostringa con corrispondenza con una nuova sottostringa.
-
{{jsxref("String.prototype.search()")}}
-
Esegue la ricerca di una corrispondenza tra un'espressione regolare e una stringa specificata.
-
{{jsxref("String.prototype.slice()")}}
-
Estrae una sezione di una stringa e restituisce una nuova stringa.
-
{{jsxref("String.prototype.split()")}}
-
Divide un oggetto  {{jsxref("Global_Objects/String", "String")}} in una matrice di stringhe separando la stringa in sottostringhe.
-
{{jsxref("String.prototype.startsWith()")}}
-
Determina se una stringa inizia con i caratteri di un'altra stringa.
-
{{jsxref("String.prototype.substr()")}} {{deprecated_inline}}
-
Restituisce i caratteri in una stringa che inizia nella posizione specificata attraverso il numero specificato di caratteri.
-
{{jsxref("String.prototype.substring()")}}
-
Restituisce i caratteri in una stringa tra due indici nella stringa.
-
{{jsxref("String.prototype.toLocaleLowerCase()")}}
-
I caratteri all'interno di una stringa vengono convertiti in minuscolo rispettando le impostazioni locali correnti. Per la maggior parte delle lingue, questo restituirà lo stesso di {{jsxref("String.prototype.toLowerCase()", "toLowerCase()")}}.
-
{{jsxref("String.prototype.toLocaleUpperCase()")}}
-
I caratteri all'interno di una stringa vengono convertiti in maiuscolo rispettando le impostazioni locali correnti. Per la maggior parte delle lingue, ciò restituirà lo stesso di {{jsxref("String.prototype.toUpperCase()", "toUpperCase()")}}.
-
{{jsxref("String.prototype.toLowerCase()")}}
-
Restituisce il valore della stringa chiamante convertito in minuscolo.
-
{{jsxref("String.prototype.toSource()")}} {{non-standard_inline}}
-
Restituisce un oggetto letterale che rappresenta l'oggetto specificato; puoi usare questo valore per creare un nuovo oggetto. Sostituisce il metodo {{jsxref("Object.prototype.toSource()")}} method.
-
{{jsxref("String.prototype.toString()")}}
-
Restituisce una stringa che rappresenta l'oggetto specificato. Sostituisce il metodo {{jsxref("Object.prototype.toString()")}} .
-
{{jsxref("String.prototype.toUpperCase()")}}
-
Restituisce il valore della stringa chiamante convertito in maiuscolo.
-
{{jsxref("String.prototype.trim()")}}
-
Taglia gli spazi bianchi all'inizio e alla fine della stringa. Parte dello standard ECMAScript 5.
-
{{jsxref("String.prototype.trimStart()")}}
- {{jsxref("String.prototype.trimLeft()")}}
-
Taglia gli spazi bianchi dall'inizio della stringa.
-
{{jsxref("String.prototype.trimEnd()")}}
- {{jsxref("String.prototype.trimRight()")}}
-
Taglia gli spazi bianchi dalla fine della stringa.
-
{{jsxref("String.prototype.valueOf()")}}
-
Restituisce il valore primitivo dell'oggetto specificato. Sostituisce il metodo {{jsxref("Object.prototype.valueOf()")}}.
-
{{jsxref("String.prototype.@@iterator()", "String.prototype[@@iterator]()")}}
-
Restituisce un nuovo oggetto Iterator che itera sopra i punti di codice di un valore String, restituendo ogni punto di codice come valore String.
-
- -

HTML metodi wrapper (involucro)

- -

Questi metodi sono di uso limitato, in quanto forniscono solo un sottoinsieme dei tag e degli attributi HTML disponibili.

- -
-
{{jsxref("String.prototype.anchor()")}} {{deprecated_inline}}
-
{{htmlattrxref("name", "a", "<a name=\"name\">")}} (hypertext target)
-
{{jsxref("String.prototype.big()")}} {{deprecated_inline}}
-
{{HTMLElement("big")}}
-
{{jsxref("String.prototype.blink()")}} {{deprecated_inline}}
-
{{HTMLElement("blink")}}
-
{{jsxref("String.prototype.bold()")}} {{deprecated_inline}}
-
{{HTMLElement("b")}}
-
{{jsxref("String.prototype.fixed()")}} {{deprecated_inline}}
-
{{HTMLElement("tt")}}
-
{{jsxref("String.prototype.fontcolor()")}} {{deprecated_inline}}
-
{{htmlattrxref("color", "font", "<font color=\"color\">")}}
-
{{jsxref("String.prototype.fontsize()")}} {{deprecated_inline}}
-
{{htmlattrxref("size", "font", "<font size=\"size\">")}}
-
{{jsxref("String.prototype.italics()")}} {{deprecated_inline}}
-
{{HTMLElement("i")}}
-
{{jsxref("String.prototype.link()")}} {{deprecated_inline}}
-
{{htmlattrxref("href", "a", "<a href=\"url\">")}} (link to URL)
-
{{jsxref("String.prototype.small()")}} {{deprecated_inline}}
-
{{HTMLElement("small")}}
-
{{jsxref("String.prototype.strike()")}} {{deprecated_inline}}
-
{{HTMLElement("strike")}}
-
{{jsxref("String.prototype.sub()")}} {{deprecated_inline}}
-
{{HTMLElement("sub")}}
-
{{jsxref("String.prototype.sup()")}} {{deprecated_inline}}
-
{{HTMLElement("sup")}}
-
- -

Specificazioni

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificazioniStatoCommento
{{SpecName('ES1')}}{{Spec2('ES1')}}Definizione iniziale.
{{SpecName('ES5.1', '#sec-15.5.3.1', 'String.prototype')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-string.prototype', 'String.prototype')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-string.prototype', 'String.prototype')}}{{Spec2('ESDraft')}} 
- -

Compatibilità con il browser

- - - -

{{Compat("javascript.builtins.String.prototype")}}

- -

Guarda anche

- - diff --git a/files/it/web/javascript/reference/operators/comma_operator/index.html b/files/it/web/javascript/reference/operators/comma_operator/index.html new file mode 100644 index 0000000000..e4027930a1 --- /dev/null +++ b/files/it/web/javascript/reference/operators/comma_operator/index.html @@ -0,0 +1,105 @@ +--- +title: Operatore virgola +slug: Web/JavaScript/Reference/Operators/Operatore_virgola +translation_of: Web/JavaScript/Reference/Operators/Comma_Operator +--- +
{{jsSidebar("Operators")}}
+ +

L'operatore virgola valuta ciascuno dei suoi operandi, da sinistra a destra, e restituisce il valore dell'ultimo operando.

+ +
{{EmbedInteractiveExample("pages/js/expressions-commaoperators.html")}}
+ + + +

Sintassi

+ +
expr1, expr2, expr3...
+ +

Parametri

+ +
+
expr1, expr2, expr3...
+
Qualsiasi espressione.
+
+ +

Descrizione

+ +

Puoi utilizzare l'operatore virgola quando vuoi includere più espressioni in una posizione che richiede una singola espressione. L'uso più comune di questo operatore è di fornire più parametri in un ciclo for.

+ +

L'operatore virgola è completamente differente dalla virgola utilizzata negli array, negli oggetti, e negli argomenti e parametri di funzione.

+ +

Esempi

+ +

Considerando a un array di 2 dimensioni contenente 10 elementi per ciascun lato, il seguente codice utilizza l'operatore virgola per incrementare i e decrementare j contemporaneamente.

+ +

Il seguente codice stampa i valori degli elementi in posizione diagonale dell'array:

+ +
for (var i = 0, j = 9; i <= 9; i++, j--)
+  console.log('a[' + i + '][' + j + '] = ' + a[i][j]);
+ +

Si noti che gli operatori virgola nelle assegnazioni potrebbero non avere l'effetto normale degli operatori virgola perché non esistono all'interno di un'espressione. Nel seguente esempio, a é impostato al valore di b = 3 (che é 3), ma l'espressione c = 4 continua a essere valutata e il suo valore viene restituito alla console (cioé 4). Questo é dovuto alla precedenza e all'associtività dell'operatore.

+ +
var a, b, c;
+
+a = b = 3, c = 4; // restituisce 4 nella console
+console.log(a); // 3 (più a sinistra)
+
+var x, y, z;
+
+x = (y = 5, z = 6); // restituisce 6 nella console
+console.log(x); // 6 (più a destra)
+
+ +

Elaborazione e restituzione

+ +

Un altro esempio che si potrebbe fare con l'operatore virgola è quello di eleborare prima di restituire. Come detto, solo l'ultimo elemento viene restituito ma anche tutti gli altri vengono valutati. Quindi, si potrebbe fare:

+ +
function myFunc() {
+  var x = 0;
+
+  return (x += 1, x); // stesso comportamento di ++x;
+}
+ +

Specificazioni

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-comma-operator', 'Comma operator')}}{{Spec2('ESDraft')}}
{{SpecName('ES6', '#sec-comma-operator', 'Comma operator')}}{{Spec2('ES6')}}
{{SpecName('ES5.1', '#sec-11.14', 'Comma operator')}}{{Spec2('ES5.1')}}
{{SpecName('ES1', '#sec-11.14', 'Comma operator')}}{{Spec2('ES1')}}Initial definition
+ +

Compatibilità con i browser

+ + + +

{{Compat("javascript.operators.comma")}}

+ +

Vedi anche

+ + diff --git a/files/it/web/javascript/reference/operators/conditional_operator/index.html b/files/it/web/javascript/reference/operators/conditional_operator/index.html new file mode 100644 index 0000000000..1ade61b085 --- /dev/null +++ b/files/it/web/javascript/reference/operators/conditional_operator/index.html @@ -0,0 +1,171 @@ +--- +title: Operatore condizionale (ternary) +slug: Web/JavaScript/Reference/Operators/Operator_Condizionale +tags: + - JavaScript Operatore operatore +translation_of: Web/JavaScript/Reference/Operators/Conditional_Operator +--- +

L'operatore condizionale (ternary) è  l'unico operatore JavaScript che necessità di tre operandi. Questo operatore è frequentemente usato al posto del comando if per la sua sintassi concisa e perché fornisce direttamente un espressione valutabile.

+ +

Sintassi

+ +
condizione ? espressione1 : espressione2 
+ +

Parametri

+ +
+
condizione
+
Un espressione booleana (che viene valutata in vero o falso).
+
+ +
+
espressione1, espressione2
+
Espressione di qualunque tipo (vedi avanti nella pagina).
+
+ +

Descrizione

+ +

Se la condizione è vera, l'operatore ritorna il valore di espressione1; altrimenti, ritorna il valore di espressione2.  Per esempio, puoi usare questa espressione per mostrare un messaggio che cambia in base al valore della variabile isMember:

+ +
"The fee is " + (isMember ? "$2.00" : "$10.00")
+
+ +

Puoi anche assegnare variabili dipendenti dal risultato di un operatore ternario:

+ +
var elvisLives = Math.PI > 4 ? "Yep" : "Nope";
+ +

Sono anche possibili espressioni con operatori ternari multipli (nota: l'operatore condizionale è associativo a destra):

+ +
var firstCheck = false,
+    secondCheck = false,
+    access = firstCheck ? "Access denied" : secondCheck ? "Access denied" : "Access granted";
+
+console.log( access ); // logs "Access granted"
+ +

Puoi anche usare l'operatore ternario direttamente senza assegnamenti e senza combinazioni con altre espressioni, con lo scopo di valutare operazioni alternative:

+ +
var stop = false, age = 16;
+
+age > 18 ? location.assign("continue.html") : stop = true;
+
+ +

Puoi anche valutare operazioni multiple separandole con delle virgole:

+ +
var stop = false, age = 23;
+
+age > 18 ? (
+    alert("OK, you can go."),
+    location.assign("continue.html")
+) : (
+    stop = true,
+    alert("Sorry, you are much too young!")
+);
+
+ +

Puoi anche valutare più operazioni durante l'assegnamento di una variabile. In questo caso, l'ultimo valore separato da una virgola nelle parentesi sarà il valore assegnato.

+ +
var age = 16;
+
+var url = age > 18 ? (
+    alert("OK, you can go."),
+    // alert returns "undefined", but it will be ignored because
+    // isn't the last comma-separated value of the parenthesis
+    "continue.html" // the value to be assigned if age > 18
+) : (
+    alert("You are much too young!"),
+    alert("Sorry :-("),
+    // etc. etc.
+    "stop.html" // the value to be assigned if !(age > 18)
+);
+
+location.assign(url); // "stop.html"
+ +

Specifiche

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-conditional-operator', 'Conditional Operator')}}{{Spec2('ESDraft')}} 
{{SpecName('ES6', '#sec-conditional-operator', 'Conditional Operator')}}{{Spec2('ES6')}} 
{{SpecName('ES5.1', '#sec-11.12', 'The conditional operator')}}{{Spec2('ES5.1')}} 
{{SpecName('ES1', '#sec-11.12', 'The conditional operator')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.0.
+ +

Compatibilità con Browser

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

Vedi anche

+ + diff --git a/files/it/web/javascript/reference/operators/operator_condizionale/index.html b/files/it/web/javascript/reference/operators/operator_condizionale/index.html deleted file mode 100644 index 1ade61b085..0000000000 --- a/files/it/web/javascript/reference/operators/operator_condizionale/index.html +++ /dev/null @@ -1,171 +0,0 @@ ---- -title: Operatore condizionale (ternary) -slug: Web/JavaScript/Reference/Operators/Operator_Condizionale -tags: - - JavaScript Operatore operatore -translation_of: Web/JavaScript/Reference/Operators/Conditional_Operator ---- -

L'operatore condizionale (ternary) è  l'unico operatore JavaScript che necessità di tre operandi. Questo operatore è frequentemente usato al posto del comando if per la sua sintassi concisa e perché fornisce direttamente un espressione valutabile.

- -

Sintassi

- -
condizione ? espressione1 : espressione2 
- -

Parametri

- -
-
condizione
-
Un espressione booleana (che viene valutata in vero o falso).
-
- -
-
espressione1, espressione2
-
Espressione di qualunque tipo (vedi avanti nella pagina).
-
- -

Descrizione

- -

Se la condizione è vera, l'operatore ritorna il valore di espressione1; altrimenti, ritorna il valore di espressione2.  Per esempio, puoi usare questa espressione per mostrare un messaggio che cambia in base al valore della variabile isMember:

- -
"The fee is " + (isMember ? "$2.00" : "$10.00")
-
- -

Puoi anche assegnare variabili dipendenti dal risultato di un operatore ternario:

- -
var elvisLives = Math.PI > 4 ? "Yep" : "Nope";
- -

Sono anche possibili espressioni con operatori ternari multipli (nota: l'operatore condizionale è associativo a destra):

- -
var firstCheck = false,
-    secondCheck = false,
-    access = firstCheck ? "Access denied" : secondCheck ? "Access denied" : "Access granted";
-
-console.log( access ); // logs "Access granted"
- -

Puoi anche usare l'operatore ternario direttamente senza assegnamenti e senza combinazioni con altre espressioni, con lo scopo di valutare operazioni alternative:

- -
var stop = false, age = 16;
-
-age > 18 ? location.assign("continue.html") : stop = true;
-
- -

Puoi anche valutare operazioni multiple separandole con delle virgole:

- -
var stop = false, age = 23;
-
-age > 18 ? (
-    alert("OK, you can go."),
-    location.assign("continue.html")
-) : (
-    stop = true,
-    alert("Sorry, you are much too young!")
-);
-
- -

Puoi anche valutare più operazioni durante l'assegnamento di una variabile. In questo caso, l'ultimo valore separato da una virgola nelle parentesi sarà il valore assegnato.

- -
var age = 16;
-
-var url = age > 18 ? (
-    alert("OK, you can go."),
-    // alert returns "undefined", but it will be ignored because
-    // isn't the last comma-separated value of the parenthesis
-    "continue.html" // the value to be assigned if age > 18
-) : (
-    alert("You are much too young!"),
-    alert("Sorry :-("),
-    // etc. etc.
-    "stop.html" // the value to be assigned if !(age > 18)
-);
-
-location.assign(url); // "stop.html"
- -

Specifiche

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-conditional-operator', 'Conditional Operator')}}{{Spec2('ESDraft')}} 
{{SpecName('ES6', '#sec-conditional-operator', 'Conditional Operator')}}{{Spec2('ES6')}} 
{{SpecName('ES5.1', '#sec-11.12', 'The conditional operator')}}{{Spec2('ES5.1')}} 
{{SpecName('ES1', '#sec-11.12', 'The conditional operator')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.0.
- -

Compatibilità con Browser

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -

Vedi anche

- - diff --git a/files/it/web/javascript/reference/operators/operatore_virgola/index.html b/files/it/web/javascript/reference/operators/operatore_virgola/index.html deleted file mode 100644 index e4027930a1..0000000000 --- a/files/it/web/javascript/reference/operators/operatore_virgola/index.html +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: Operatore virgola -slug: Web/JavaScript/Reference/Operators/Operatore_virgola -translation_of: Web/JavaScript/Reference/Operators/Comma_Operator ---- -
{{jsSidebar("Operators")}}
- -

L'operatore virgola valuta ciascuno dei suoi operandi, da sinistra a destra, e restituisce il valore dell'ultimo operando.

- -
{{EmbedInteractiveExample("pages/js/expressions-commaoperators.html")}}
- - - -

Sintassi

- -
expr1, expr2, expr3...
- -

Parametri

- -
-
expr1, expr2, expr3...
-
Qualsiasi espressione.
-
- -

Descrizione

- -

Puoi utilizzare l'operatore virgola quando vuoi includere più espressioni in una posizione che richiede una singola espressione. L'uso più comune di questo operatore è di fornire più parametri in un ciclo for.

- -

L'operatore virgola è completamente differente dalla virgola utilizzata negli array, negli oggetti, e negli argomenti e parametri di funzione.

- -

Esempi

- -

Considerando a un array di 2 dimensioni contenente 10 elementi per ciascun lato, il seguente codice utilizza l'operatore virgola per incrementare i e decrementare j contemporaneamente.

- -

Il seguente codice stampa i valori degli elementi in posizione diagonale dell'array:

- -
for (var i = 0, j = 9; i <= 9; i++, j--)
-  console.log('a[' + i + '][' + j + '] = ' + a[i][j]);
- -

Si noti che gli operatori virgola nelle assegnazioni potrebbero non avere l'effetto normale degli operatori virgola perché non esistono all'interno di un'espressione. Nel seguente esempio, a é impostato al valore di b = 3 (che é 3), ma l'espressione c = 4 continua a essere valutata e il suo valore viene restituito alla console (cioé 4). Questo é dovuto alla precedenza e all'associtività dell'operatore.

- -
var a, b, c;
-
-a = b = 3, c = 4; // restituisce 4 nella console
-console.log(a); // 3 (più a sinistra)
-
-var x, y, z;
-
-x = (y = 5, z = 6); // restituisce 6 nella console
-console.log(x); // 6 (più a destra)
-
- -

Elaborazione e restituzione

- -

Un altro esempio che si potrebbe fare con l'operatore virgola è quello di eleborare prima di restituire. Come detto, solo l'ultimo elemento viene restituito ma anche tutti gli altri vengono valutati. Quindi, si potrebbe fare:

- -
function myFunc() {
-  var x = 0;
-
-  return (x += 1, x); // stesso comportamento di ++x;
-}
- -

Specificazioni

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-comma-operator', 'Comma operator')}}{{Spec2('ESDraft')}}
{{SpecName('ES6', '#sec-comma-operator', 'Comma operator')}}{{Spec2('ES6')}}
{{SpecName('ES5.1', '#sec-11.14', 'Comma operator')}}{{Spec2('ES5.1')}}
{{SpecName('ES1', '#sec-11.14', 'Comma operator')}}{{Spec2('ES1')}}Initial definition
- -

Compatibilità con i browser

- - - -

{{Compat("javascript.operators.comma")}}

- -

Vedi anche

- - diff --git a/files/it/web/javascript/reference/operators/operatori_aritmetici/index.html b/files/it/web/javascript/reference/operators/operatori_aritmetici/index.html deleted file mode 100644 index e49fe045ae..0000000000 --- a/files/it/web/javascript/reference/operators/operatori_aritmetici/index.html +++ /dev/null @@ -1,292 +0,0 @@ ---- -title: Operatori Aritmetici -slug: Web/JavaScript/Reference/Operators/Operatori_Aritmetici -tags: - - JavaScript - - Operatori - - Operatori Aritmetici -translation_of: Web/JavaScript/Reference/Operators -translation_of_original: Web/JavaScript/Reference/Operators/Arithmetic_Operators ---- -
{{jsSidebar("Operators")}}
- -
Gli operatori aritmetici lavorano su operandi numerici (sia letterali che variabili) e ritornano un singolo valore numerico. Gli operatori aritmetici standard sono l'addizione (+), la sottrazione (-), la moltiplicazione (*) e la divisione (/).
- -

Addizione (+)

- -

L'operazione di addizione produce la somma di operandi numerici o la concatenzione di stringhe.

- -

Sintassi

- -
Operatore: x + y
-
- -

Esempi

- -
// Numero + Numero -> addizione
-1 + 2 // 3
-
-// Booleano + Numero -> addizione
-true + 1 // 2
-
-// Booleano + Booleano -> additione
-false + false // 0
-
-// Numero + Stringa -> concatenazione
-5 + "foo" // "5foo"
-
-// Stringa + Booleano -> concatenazione
-"foo" + false // "foofalse"
-
-// Stringa + Stringa -> concatenazione
-"foo" + "bar" // "foobar"
-
- -

Sottrazione (-)

- -

L'operatore di sottrazione fa la sottrazione dei due operandi e produce la loro differenza.

- -

Sintassi

- -
Operatore: x - y
-
- -

Esempi

- -
5 - 3 // 2
-3 - 5 // -2
-"foo" - 3 // NaN
- -

Divisione (/)

- -

L'operatore di divisione produce il quoziente dei suoi operandi dove l'operando di sinistra è il dividendo e l'operando di destra è il divisore.

- -

Sintassi

- -
Operatore: x / y
-
- -

Esempi

- -
1 / 2      // restituisce 0.5 in JavaScript
-1 / 2      // restituisce 0 in Java
-// (nessuno degli operandi è un numero in virgola mobile esplicito)
-
-1.0 / 2.0  // restituisce 0.5 in both JavaScript and Java
-
-2.0 / 0    // restituisce Infinity in JavaScript
-2.0 / 0.0  // restituisce Infinity too
-2.0 / -0.0 // restituisce -Infinity in JavaScript
- -

Moltiplicazione (*)

- -

The multiplication operator produces the product of the operands.

- -

Sintassi

- -
Operatore: x * y
-
- -

Esempi

- -
2 * 2 // 4
--2 * 2 // -4
-Infinity * 0 // NaN
-Infinity * Infinity // Infinity
-"foo" * 2 // NaN
-
- -

Resto (%)

- -

L'operatore Resto o Modulo restituisce il “resto“ rimasto quando un operando viene diviso per un secondo operando. Calcola il resto della divisione fra il primo e il secondo operando. Porta sempre il segno del dividendo.

- -

Sintassi

- -
Operatore: var1 % var2
-
- -

Esempi

- -
12 % 5 // 2
--1 % 2 // -1
-NaN % 2 // NaN
-1 % 2 // 1
-2 % 3 // 2
--4 % 2 // -0
-
- -

Esponente (**)

- -

L'operatore Esponente o esponenziale in JavaScript. Una delle funzionalità di questa versione è l'operatore di esponenziazione. Esponente restituisce il risultato dell'elevamento a potenza dal primo operando al secondo. Cioè var1 var2 , var2. var1var2 sono variabili. L'operatore Esponente ha ragione associativa. a ** b ** c equivale a a ** (b ** c).

- -

Sintassi

- -
Operatore: var1 ** var2
-
- -

Note

- -

Nella maggior parte dei linguaggi come PHP e Python e altri che usano l'operatore Esponente (**), ha precedenza rispetto agli altri operatori unari come + e -, salvo in alcune eccezioni. Ad esempio, in Bash l'operatore ** ha una minor importanza rispetto agli operatori unari. In JavaScript, è impossibile scrivere un'espressione Esponente ambigua, ovvero non è possibile inserire un operatore unario ( +/-/~/!/delete/void/typeof ) immediatamente prima del numero di base. Il calcolo della potenza può essere espresso più sinteticamente usando la notazione infissa. Simile ad altri linguaggi come Python o F#, ** è usato per indicare l'operatore. 

- -
-2 ** 2 // equals 4 in ES2016 or in Bash, equals -4 in other languages.
- -

Accetta base sul lato sinistro ed esponente sul lato destro, rispettivamente.

- -
let value = 5; value **= 2; // value: 25
-
- -

Esempi

- -
2 ** 3 // 8
-3 ** 2 // 9
-3 ** 2.5 // 15.588457268119896
-10 ** -1 // 0.1
-NaN ** 2 // NaN
-
-2 ** 3 ** 2 // 512
-2 ** (3 ** 2) // 512
-(2 ** 3) ** 2 // 64
-
-var a = 3;
-var b = a ** 3;
-alert("3x3x3 is = " + b); // 27
-
- -

Per invertire il segno del risultato di un'espressione di Esponente:

- -
-(2 ** 2) // -4
-
- -

Per forzare la base di un'espressione di Esponente ad essere un numero negativo:

- -
(-2) ** 2 // 4 
- -

Incremento (++)

- -

L'operatore di incremento incrementa (aggiunge uno a) il suo operando e restituisce un valore.

- - - -

Sintassi

- -
Operatore: x++ or ++x
-
- -

Esempi

- -
// Postfix // post posizione
-var x = 3;
-y = x++; // y = 3, x = 4
-
-// Prefix // Prefisso
-var a = 2;
-b = ++a; // a = 3, b = 3
-
- -

Decremento (--)

- -

L'operatore decrementa decrementa (sottrae uno da) il suo operando e restituisce un valore.

- - - -

Sintassi

- -
Operatore: x-- or --x
-
- -

Esempi

- -
// Postfix // post posizione
-var x = 3;
-y = x--; // y = 3, x = 2
-
-// Prefix // Prefisso
-var a = 2;
-b = --a; // a = 1, b = 1
-
- -

Negazione unaria (-)

- -

L'operatore di negazione unario precede il suo operando e lo nega.

- -

Sintassi

- -
Operatore: -x
-
- -

Esempi

- -
var x = 3;
-y = -x; // y = -3, x = 3
-
-//L'operatore di negazione unario può convertire numeri diversi in un numero
-var x = "4";
-y = -x; // y = -4
- -

Unario più (+)

- -

L'operatore unario più precede il suo operando e valuta il suo operando, ma tenta di convertirlo in un numero, se non lo è già. Anche se la negazione unaria (-) può anche convertire non numeri, unario è il modo più veloce e preferito per convertire qualcosa in un numero, perché non esegue altre operazioni sul numero. È in grado di convertire rappresentazioni di stringa di numeri interi e float, oltre ai valori non stringa true , false e null . Sono supportati i numeri interi decimali ed esadecimali ("0x" -prefixed). I numeri negativi sono supportati (sebbene non per hex). Se non può analizzare un valore particolare, valuterà in NaN.

- -

Sintassi

- -
Operatore: +x
-
- -

Esempi

- -
+3     // 3
-+'3'   // 3
-+true  // 1
-+false // 0
-+null  // 0
-+function(val){  return val } // NaN
- -

Specificazioni

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificazioniStatoCommento
ECMAScript 1st Edition.StandardDefinizione iniziale.
{{SpecName('ES5.1', '#sec-11.3')}}{{Spec2('ES5.1')}}Definito in diverse sezioni della specifica: Additive operators, Multiplicative operators, Postfix expressions, Unary operators.
{{SpecName('ES2015', '#sec-postfix-expressions')}}{{Spec2('ES2015')}}Definito in diverse sezioni della specifica: Additive operators, Multiplicative operators, Postfix expressions, Unary operators.
{{SpecName('ES2016', '#sec-postfix-expressions')}}{{Spec2('ES2016')}}Aggiunto Exponentiation operator.
- -

Compatibilità con i browser

- - - -

{{Compat("javascript.operators.arithmetic")}}

- -

Guarda anche

- - diff --git a/files/it/web/javascript/reference/template_literals/index.html b/files/it/web/javascript/reference/template_literals/index.html new file mode 100644 index 0000000000..5bb4890ad8 --- /dev/null +++ b/files/it/web/javascript/reference/template_literals/index.html @@ -0,0 +1,210 @@ +--- +title: Stringhe template +slug: Web/JavaScript/Reference/template_strings +translation_of: Web/JavaScript/Reference/Template_literals +--- +
{{JsSidebar("More")}}
+ +

Le stringhe template sono stringhe letterali che consentono espressioni incorporate. Puoi usare stringhe multi-linea e caratteristiche di interpolazione stringa con esse.

+ +

Sintassi

+ +
`stringa testo`
+
+`stringa testo linea 1
+ stringa testo linea 2`
+
+`stringa testo ${espressione} stringa testo`
+
+tag `stringa testo ${espressione} stringa testo`
+
+ +

Descrizione

+ +

Le stringhe template sono racchiuse dal carattere backtick (` `) (accento grave) invece delle singole o doppie virgolette. Le stringhe template possono contenere segnaposti. Questi sono indicati dal segno del Dollaro e parentesi graffe (${espressione}). Le espressioni nei segnaposti e nel testo compreso vengono passati ad una funzione. La funzione predefinita semplicemente concatena le parti in una stringa. Se c'è un'espressione che precede (tag qui), la stringa template è chiamata "stringa template taggata". In questo caso, l'espressione tag (di solito una funzione) viene chiamata con la stringa template processata, con cui puoi in seguito manipolare prima dell'output.

+ +

Stringhe multilinea

+ +

Ogni carattere di nuova linea inseriti nel sorgente sono parte della stringa template. Usando stringhe normali, potresti usare la seguente sintassi per ottenere stringhe multilinea:

+ +
console.log("stringa testo linea 1\n"+
+"stringa testo linea 2");
+// "stringa testo linea 1
+// stringa testo linea 2"
+ +

Per avere lo stesso effetto con le stringhe multilinea, puoi adesso scrivere:

+ +
console.log(`stringa testo linea 1
+stringa testo linea 2`);
+// "stringa testo linea 1
+// stringa testo linea 2"
+ +

Interpolazione di espressioni

+ +

Per incorporare espressioni dentro normale stringhe, potresti fare uso della seguente sintassi:

+ +
var a = 5;
+var b = 10;
+console.log("Quindici è " + (a + b) + " e\nnon " + (2 * a + b) + ".");
+// "Quindici è 15 e
+// non 20."
+ +

Adesso, con le stringhe template, puoi fare uso della sintassi ridotta facendo sostituzioni come questa più leggibile:

+ +
var a = 5;
+var b = 10;
+console.log(`Quindici è ${a + b} e\nnon ${2 * a + b}.`);
+// "Quindici è 15 e
+// non 20."
+ +

Stringhe template taggate

+ +

Una forma più avanzata di stringhe template sono le stringhe template taggate. Con esse puoi modificare l'output delle stringhe template usando una funzione. Il primo argomento contiene un array di stringhe letterali ("Ciao" e " mondo" in questo esempio). Il secondo, ed ogni argomento dopo il primo, sono i valori delle espressioni di sostituzione ("15" e "50" qui) processate (o a volte detto lavorate). Alla fine, la tua funzione ritorna la stringa manipolata. Non c'è nulla di speciale sul nome tag nel seguente esempio. Il nome della funzione può essere qualsiasi cosa tu voglia.

+ +
var a = 5;
+var b = 10;
+
+function tag(strings, ...values) {
+  console.log(strings[0]); // "Ciao "
+  console.log(strings[1]); // " mondo "
+  console.log(values[0]);  // 15
+  console.log(values[1]);  // 50
+
+  return "Bazinga!";
+}
+
+tag`Ciao ${ a + b } mondo ${ a * b }`;
+// "Bazinga!"
+
+ +

Le funzioni Tag non devono per forza ritornare una stringa, come mostrato nel seguente esempio.

+ +
function template(strings, ...keys) {
+  return (function(...values) {
+    var dict = values[values.length - 1] || {};
+    var result = [strings[0]];
+    keys.forEach(function(key, i) {
+      var value = Number.isInteger(key) ? values[key] : dict[key];
+      result.push(value, strings[i + 1]);
+    });
+    return result.join('');
+  });
+}
+
+template`${0}${1}${0}!`('Y', 'A');  // "YAY!"
+template`${0} ${'foo'}!`('Ciao', {foo: 'Mondo'});  // "Ciao Mondo!"
+
+ +

Stringhe grezze

+ +

La proprietà speciale raw, disponibile sull'argomento della prima funzione delle stringhe template taggate, ti consente di accedere alle stringhe grezze per come sono state inserite.

+ +
function tag(strings, ...values) {
+  console.log(strings.raw[0]);
+  // "stringa testo linea 1 \\n stringa testo linea 2"
+}
+
+tag`stringa testo linea 1 \n stringa testo linea 2`;
+
+ +

In aggiunta, il metodo {{jsxref("String.raw()")}} esiste per creare stringhe grezze proprio come la funzione template predefinita e contatenazione di stringhe potrebbero creare.

+ +
String.raw`Salve\n${2+3}!`;
+// "Salve\n5!"
+ +

Sicurezza

+ +

Le stringhe template NON DEVONO essere costruite da utenti non fidati, poichè hanno accesso a variabili e funzioni.

+ +
`${console.warn("this is",this)}`; // "this is" Window
+
+let a = 10;
+console.warn(`${a+=20}`); // "30"
+console.warn(a); // 30
+
+ +

Specifiche

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-template-literals', 'Template Literals')}}{{Spec2('ES6')}}Definizione iniziale. Definita in molte sezioni della specifica: Template Literals, Tagged Templates
{{SpecName('ESDraft', '#sec-template-literals', 'Template Literals')}}{{Spec2('ESDraft')}}Definita in molte sezioni della specifica: Template Literals, Tagged Templates
+ +

Compatibilità browser

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + +
CaratteristicaChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Supporto base{{CompatChrome(41)}}{{CompatVersionUnknown}}{{CompatGeckoDesktop("34")}}{{CompatNo}}{{CompatOpera(28)}}{{CompatSafari(9)}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
CaratteristicaAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Supporto base{{CompatNo}}{{CompatChrome(41)}}{{CompatGeckoMobile("34")}}{{CompatNo}}{{CompatOpera(28)}}{{CompatSafari(9)}}
+
+ +

Vedi anche

+ + diff --git a/files/it/web/javascript/reference/template_strings/index.html b/files/it/web/javascript/reference/template_strings/index.html deleted file mode 100644 index 5bb4890ad8..0000000000 --- a/files/it/web/javascript/reference/template_strings/index.html +++ /dev/null @@ -1,210 +0,0 @@ ---- -title: Stringhe template -slug: Web/JavaScript/Reference/template_strings -translation_of: Web/JavaScript/Reference/Template_literals ---- -
{{JsSidebar("More")}}
- -

Le stringhe template sono stringhe letterali che consentono espressioni incorporate. Puoi usare stringhe multi-linea e caratteristiche di interpolazione stringa con esse.

- -

Sintassi

- -
`stringa testo`
-
-`stringa testo linea 1
- stringa testo linea 2`
-
-`stringa testo ${espressione} stringa testo`
-
-tag `stringa testo ${espressione} stringa testo`
-
- -

Descrizione

- -

Le stringhe template sono racchiuse dal carattere backtick (` `) (accento grave) invece delle singole o doppie virgolette. Le stringhe template possono contenere segnaposti. Questi sono indicati dal segno del Dollaro e parentesi graffe (${espressione}). Le espressioni nei segnaposti e nel testo compreso vengono passati ad una funzione. La funzione predefinita semplicemente concatena le parti in una stringa. Se c'è un'espressione che precede (tag qui), la stringa template è chiamata "stringa template taggata". In questo caso, l'espressione tag (di solito una funzione) viene chiamata con la stringa template processata, con cui puoi in seguito manipolare prima dell'output.

- -

Stringhe multilinea

- -

Ogni carattere di nuova linea inseriti nel sorgente sono parte della stringa template. Usando stringhe normali, potresti usare la seguente sintassi per ottenere stringhe multilinea:

- -
console.log("stringa testo linea 1\n"+
-"stringa testo linea 2");
-// "stringa testo linea 1
-// stringa testo linea 2"
- -

Per avere lo stesso effetto con le stringhe multilinea, puoi adesso scrivere:

- -
console.log(`stringa testo linea 1
-stringa testo linea 2`);
-// "stringa testo linea 1
-// stringa testo linea 2"
- -

Interpolazione di espressioni

- -

Per incorporare espressioni dentro normale stringhe, potresti fare uso della seguente sintassi:

- -
var a = 5;
-var b = 10;
-console.log("Quindici è " + (a + b) + " e\nnon " + (2 * a + b) + ".");
-// "Quindici è 15 e
-// non 20."
- -

Adesso, con le stringhe template, puoi fare uso della sintassi ridotta facendo sostituzioni come questa più leggibile:

- -
var a = 5;
-var b = 10;
-console.log(`Quindici è ${a + b} e\nnon ${2 * a + b}.`);
-// "Quindici è 15 e
-// non 20."
- -

Stringhe template taggate

- -

Una forma più avanzata di stringhe template sono le stringhe template taggate. Con esse puoi modificare l'output delle stringhe template usando una funzione. Il primo argomento contiene un array di stringhe letterali ("Ciao" e " mondo" in questo esempio). Il secondo, ed ogni argomento dopo il primo, sono i valori delle espressioni di sostituzione ("15" e "50" qui) processate (o a volte detto lavorate). Alla fine, la tua funzione ritorna la stringa manipolata. Non c'è nulla di speciale sul nome tag nel seguente esempio. Il nome della funzione può essere qualsiasi cosa tu voglia.

- -
var a = 5;
-var b = 10;
-
-function tag(strings, ...values) {
-  console.log(strings[0]); // "Ciao "
-  console.log(strings[1]); // " mondo "
-  console.log(values[0]);  // 15
-  console.log(values[1]);  // 50
-
-  return "Bazinga!";
-}
-
-tag`Ciao ${ a + b } mondo ${ a * b }`;
-// "Bazinga!"
-
- -

Le funzioni Tag non devono per forza ritornare una stringa, come mostrato nel seguente esempio.

- -
function template(strings, ...keys) {
-  return (function(...values) {
-    var dict = values[values.length - 1] || {};
-    var result = [strings[0]];
-    keys.forEach(function(key, i) {
-      var value = Number.isInteger(key) ? values[key] : dict[key];
-      result.push(value, strings[i + 1]);
-    });
-    return result.join('');
-  });
-}
-
-template`${0}${1}${0}!`('Y', 'A');  // "YAY!"
-template`${0} ${'foo'}!`('Ciao', {foo: 'Mondo'});  // "Ciao Mondo!"
-
- -

Stringhe grezze

- -

La proprietà speciale raw, disponibile sull'argomento della prima funzione delle stringhe template taggate, ti consente di accedere alle stringhe grezze per come sono state inserite.

- -
function tag(strings, ...values) {
-  console.log(strings.raw[0]);
-  // "stringa testo linea 1 \\n stringa testo linea 2"
-}
-
-tag`stringa testo linea 1 \n stringa testo linea 2`;
-
- -

In aggiunta, il metodo {{jsxref("String.raw()")}} esiste per creare stringhe grezze proprio come la funzione template predefinita e contatenazione di stringhe potrebbero creare.

- -
String.raw`Salve\n${2+3}!`;
-// "Salve\n5!"
- -

Sicurezza

- -

Le stringhe template NON DEVONO essere costruite da utenti non fidati, poichè hanno accesso a variabili e funzioni.

- -
`${console.warn("this is",this)}`; // "this is" Window
-
-let a = 10;
-console.warn(`${a+=20}`); // "30"
-console.warn(a); // 30
-
- -

Specifiche

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES6', '#sec-template-literals', 'Template Literals')}}{{Spec2('ES6')}}Definizione iniziale. Definita in molte sezioni della specifica: Template Literals, Tagged Templates
{{SpecName('ESDraft', '#sec-template-literals', 'Template Literals')}}{{Spec2('ESDraft')}}Definita in molte sezioni della specifica: Template Literals, Tagged Templates
- -

Compatibilità browser

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - - - -
CaratteristicaChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Supporto base{{CompatChrome(41)}}{{CompatVersionUnknown}}{{CompatGeckoDesktop("34")}}{{CompatNo}}{{CompatOpera(28)}}{{CompatSafari(9)}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
CaratteristicaAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Supporto base{{CompatNo}}{{CompatChrome(41)}}{{CompatGeckoMobile("34")}}{{CompatNo}}{{CompatOpera(28)}}{{CompatSafari(9)}}
-
- -

Vedi anche

- - diff --git a/files/it/web/javascript/una_reintroduzione_al_javascript/index.html b/files/it/web/javascript/una_reintroduzione_al_javascript/index.html deleted file mode 100644 index 4dc4a484a7..0000000000 --- a/files/it/web/javascript/una_reintroduzione_al_javascript/index.html +++ /dev/null @@ -1,966 +0,0 @@ ---- -title: Una reintroduzione al Java Script (Tutorial JS) -slug: Web/JavaScript/Una_reintroduzione_al_JavaScript -translation_of: Web/JavaScript/A_re-introduction_to_JavaScript ---- -

Introduzione

- -

Perchè una reintroduzione? Perchè  JavaScript ha la ragionevole pretesa di essere il linguaggio di programmazione più frainteso del mondo. Benchè spesso considerato ironicamente come un giocattolo, la sua ingannevole semplicità nasconde alcune potenti caratteristiche. JavaScript viene attualmente utilizzato da un numero incredibile di applicazioni di alto profilo, che mostrano come la conoscenza profonda di questa tecnologia sia un importante abilità per qualunque sviluppatore web.

- -

È utile iniziare con un accenno alla storia del linguaggio. JavaScript fu creato nel 1995 da Brendan Eich, mentre lavorava come ingegnere presso Netscape, e rilasciata per la prima volta con Netscape 2 all'inizio del 1996. Originariamente doveva essere chiamato LiveScript, ma fu poi rinominato in Javacript per una fatalmente dannosa decisione di marketing che tentava di approfittare della popolarità del linguaggio Java della Sun Microsystem — nonostante abbiano molto poco in comune. Questa è stata una fonte di confusione da allora.

- -

Diversi mesi dopo, Microsoft rilasciò JScript con Internet Explorer 3, un linguaggio che lavorava in modo simile a JavaScript ed era quasi del tutto compatibile con esso. Netscape sottomise il linguaggio alla Ecma International, un'organizzazione europea di standardizzazione, che porta alla nascita della prima edizione degli standard ECMAScript. Lo standard ricevette un significativo aggiornamento come ECMAScript edition 3 nel 1999, ed è rimasto più o meno stabile da allora. La quarta edizione fu abbandonata a causa delle differenze di vedute sulla complessità del linguaggio. Molte parti della quarta edizione formano la base del nuovo ECMAScript edizione 5, pubblicato nel dicembre del 2009, e per la sesta edizione pubblicata a giugno 2015.

- -

Diversamente dalla maggior parte dei linguaggi di programmazione, il linguaggio JavaScript non ha il concetto di input e output. È stato concepito per essere eseguito come linguaggio di scripting in un ambiente ospite, ed è responsabilità dell'ambiente ospite fornire meccanismi per comunicare con il mondo esterno. L'ambiente ospite più comune è il browser, ma interpreti JavaScript possono essere trovati anche in Adobe Acrobat, Photoshop, motore Widget di Yahoo! , e addirittura in ambienti lato server o in desktop environment come GNOME (una delle GUI più popolari per i sistemi GNU/Linux) e altri ancora.

- -

Panoramica

- -

JavaScript è un linguaggio dinamico orientato agli oggetti; esso ha tipi e operatori, oggetti nucleo, e metodi. La sua sintassi deriva dai linguaggi Java e C, quindi molte strutture utilizzate da questi linguaggi ricorrono anche in JavaScript. Una delle differenze chiave è che JavaScript non ha classi; invece, la funzionalità di classe è realizzata dai prototipi oggetto. L'altra differenza principale è che le funzioni sono oggetti, dando alle funzioni la capacità di mantenere codice eseguibile ed essere passate in giro come ogni altro oggetto.

- -

Cominciamo guardando il blocco di costruzione di qualsiasi linguaggio: i tipi. I programmmi JavaScript manipolano valori, e tutti quei valori appartengono ad un tipo. I tipi JavaScript sono:

- - - -

... oh, e Undefined (indefiniti) e Null (nulli), che sono leggermente strani. E gli Array, che sono un tipo speciale di oggetto. E Date ed Espressioni regolari, che sono oggetti che si ottengono gratuitamente. E per essere tecnicamente precisi, le funzioni sono solo un tipo speciale di oggetto. Quindi il diagramma dei tipi somiglia più a questo:

- - - -

E ci sono anche alcuni tipi nativi di Errori. Comunque, le cose sono molto più semplici se ci atteniamo al primo diagramma

- -

Numeri

- -

I numeri in JavaScript sono in formato 64-bit a doppia precisione valore del IEEE 754, secondo le specifiche. Questo ha qualche interessante conseguenza. Non esiste una cosa come un intero in JavaScript, quindi bisogna stare un pò attenti con la vostra aritmetica, se siete abituati alla matematica in C o Java. Stare attenti a cose come:

- -
0.1 + 0.2 == 0.30000000000000004
-
- -

In pratica, i valori interi sono trattati come int a 32-bit (e sono memorizzati in questo modo in alcune implementazioni dei browser), che può essere importante per operazioni in bit. Per dettagli, consulta La Guida Completa sui Numeri JavaScript.

- -

Gli operatori numerici standard sono supportati, incluso addizione, sottrazione, modulo (o resto) aritmetico e così via. Vi sono anche oggetti nativi che non sono stati menzionati prima, chiamati Math per trattare funzioni matematiche più avanzate e costanti:

- -
Math.sin(3.5);
-var d = Math.PI * r * r;
-
- -

E' possibile convertire una stringa in un intero utilizzando la funzione nativa parseInt(). Questo prende la base per la conversione come secondo argomento opzionale, che si dovrebbe fornire sempre:

- -
> parseInt("123", 10)
-123
-> parseInt("010", 10)
-10
-
- -

Se non si fornisce la base, si possono ricevere risultati inattesi:

- -
> parseInt("010")
-8
-
- -

Questo succede perchè la funzione parseInt ha deciso di trattare la stringa come un ottale a causa del primo 0.

- -

Se si vuole convertire un numero binario in un intero, basta cambiare la base:

- -
> parseInt("11", 2)
-3
-
- -

Similmente, è possibile analizzare numeri in virgola mobile usando la funzione nativa parseFloat() che utilizza sempre la base 10 diversamente dalla cugina parseInt().

- -

E' inoltre possibile utilizzare l'operatore unario + per convertire valori in numeri:

- -
> + "42"
-42
-
- -

Un valore speciale chiamato NaN (abbreviazione per "Not a Number" - Non un Numero) viene restituita se la stringa non è numerica:

- -
> parseInt("hello", 10)
-NaN
-
- -

Il NaN è tossico: se viene fornito come input a qualsiasi operazione matematica, il risultato sarà anch'esso NaN:

- -
> NaN + 5
-NaN
-
- -

E' possibile verificare se NaN usando la funzione nativa isNaN():

- -
> isNaN(NaN)
-true
-
- -

Anche JavaScript ha i valori speciali Infinity-Infinity:

- -
> 1 / 0
-Infinity
-> -1 / 0
--Infinity
-
- -

E' possibile analizzare i valori Infinity, -Infinity e NaN usando la funzione nativa isFinite():

- -
> isFinite(1/0)
-false
-> isFinite(-Infinity)
-false
-> isFinite(NaN)
-false
-
- -
Nota: Le funzioni parseInt() e parseFloat() analizzano una stringa finchè raggiungono un carattere che è non è valido per il formato numerico specificato, quindi restituiscono il numero analizzato fino a quel punto. Tuttavia l'operatore "+" converte semplicemente la stringa a NaN se è presente in essa qualche carattere invalido. E' sufficiente provare ad eseguire l'analisi della stringa "10.2abc" con ogni metodo da soli utilizzando la console e sarà possibile capire meglio le differenze.
- -

Stringhe

- -

Le stringhe in JavaScript sono sequenze di caratteri. Più precisamente, sono sequenze di Caratteri Unicode, con ogni carattere rappresentato da un numero a 16-bit. Questa dovrebbe essere una buona notizia per tutti coloro che hanno avuto a che fare con l'internazionalizzazione.

- -

Se si vuole rappresentare un singolo carattere, occorre semplicemente utilizzare una stringa di lunghezza 1.

- -

Per trovare la lunghezza di una stringa, accedere la sua proprietà length:

- -
> "hello".length
-5
-
- -

Ecco il nostro primo assaggio degli oggetti JavaScript! E' stato menzionato che le stringhe sono anch'esse oggetti? Ed hanno anche metodi:

- -
> "hello".charAt(0)
-h
-> "hello, world".replace("hello", "goodbye")
-goodbye, world
-> "hello".toUpperCase()
-HELLO
-
- -

Altri tipi

- -

JavaScript distingue tra null, che è un oggetto di tipo 'object' che indica un mancanza deliberata di valore, e undefined, che è un oggetto di tipo 'undefined' che indica un valore non inizializzato — ossia un valore che non è stato ancora assegnato. Parleremo delle variabili più avanti, ma in JavaScript è possibile dichiarare una variabile senza assegnarle un valore. Facendo questo, il tipo della variabile creata sarà undefined.

- -

JavaScript ha il tipo booleano, con possibili valori true (vero) e false (falso) (entrambi i quali sono parole chiave). Qualunque valore può essere convertito in booleano seguendo le seguenti regole:

- -
    -
  1. false, 0, la stringa vuota (""), NaN, null, e undefined diventano tutti false
  2. -
  3. tutti gli altri valori diventano true
  4. -
- -

E' possibile eseguire questa conversione esplicitamente usando la funzione Boolean():

- -
> Boolean("")
-false
-> Boolean(234)
-true
-
- -

Tuttavia, questo raramente è necessario, JavaScript eseguirà silenziosamente la conversione quando si aspetta un booleano, così come in una istruzione  if (vedi sotto). Per questa ragione, a volte si parla semplicemente di "valori veri" e "valori falsi" valori significativi che diventano true e false, rispettivamente, quando convertiti in booleani. In alternativa, tali valori possono essere chiamati "truthy" e "falsy", rispettivamente.

- -

Le operazioni booleane come && (and logico), || (or logico), e ! (not logico) sono supportate; vedi sotto.

- -

Variabili

- -

Le nuove varibili sono dichiarate in JavaScript utilizzando la parola chiave var:

- -
var a;
-var name = "simon";
-
- -

Se la variabile viene dichiarata senza assegnarle un valore, il suo tipo sarà undefined

- -

Una differenza importante rispetto ad altri linguaggi come Java è che in JavaScript, i blocchi non hanno ambito; solo le funzioni hanno ambito. Quindi se una variabile viene definita utilizzando var in una istruzione composta (ad esempio all'interno di una struttura di controllo if), essa sarà visibile da parte dell'intera funzione.

- -

Operatori

- -

Gli operatori numerici in JavaScript sono +, -, *, /% - che è l'operatore per il resto. I valori sono assegnanti usando =, e vi sono anche le istruzioni di assegnamento composte tipo += e -=. Questi comprimono la forma x = x operatore y.

- -
x += 5
-x = x + 5
-
- -

E' possibile utilizzare ++ e -- per incrementare e decrementare rispettivamente. Questi possono essere usati come operatori prefissi o postfissi.

- -

L'operatore + compie anche la concatenazione di stringhe:

- -
> "hello" + " world"
-hello world
-
- -

Se si somma una stringa ad un numero (o ad un altro valore) tutto viene convertito dalla prima stringa. Questo esempio potrebbe aiutare a chiarire il tutto:

- -
> "3" + 4 + 5
-345
-> 3 + 4 + "5"
-75
-
- -

Sommare una stringa vuota ad un altro tipo è un utile maniera per convertirlo.

- -

I confronti in JavaScript possono essere eseguiti usando <, >, <= e >=. Essi funzionano sia per le stringhe che per i numeri. L'uguaglianza è un pochino meno lineare. L'operatore di doppio uguale esegue la coercizione di tipo se viene eseguita tra tipi differenti, con a volte risultati interessanti:

- -
> "dog" == "dog"
-true
-> 1 == true
-true
-
- -

Per evitare la coercizione di tipo, si utilizza l'operatore triplo uguale:

- -
> 1 === true
-false
-> true === true
-true
-
- -

Vi sono anche gli operatori !=!== .

- -

JavaScript ha inoltre le operazioni bit per bit. Se si desidera utilizzarle, sono lì.

- -

Strutture di controllo

- -

JavaScript ha una serie di strutture di controllo simili agli altri linguaggi della famiglia del C. Le istruzioni condizionali sono supportate da if e else (se e altrimenti) che possono essere concatenati insieme se desiderato:

- -
var name = "kittens";
-if (name == "puppies") {
-  name += "!";
-} else if (name == "kittens") {
-  name += "!!";
-} else {
-  name = "!" + name;
-}
-name == "kittens!!"
-
- -

JavaScript ha il ciclo while ed il ciclo do-while. Il primo è utile per un ciclo basico; il secondo per i cicli che si vuole essere sicuri che vengano eseguiti almeno una volta:

- -
while (true) {
-  // an infinite loop!
-}
-
-var input;
-do {
-  input = get_input();
-} while (inputIsNotValid(input))
-
- -

Il ciclo for in JavaScript è lo stesso che in C e Java: esso permette di fornire le informazioni di controllo per il ciclo in una linea singola.

- -
for (var i = 0; i < 5; i++) {
-  // Will execute 5 times
-}
-
- -

Gli operatori &&(and logico) e ||(or logico) usano un corto-circuito logico, questo significa che quando vengono eseguiti il secondo operando è dipendente dal primo. Questo è utile per verificare oggetti nulli prima di accedere ai loro attributi:

- -
var name = o && o.getName();
-
- -

Oppure per impostare valori di default:

- -
var name = otherName || "default";
-
- -

JavaScript ha un operatore ternario per espressioni condizionali:

- -
var allowed = (age > 18) ? "yes" : "no";
-
- -

L'istruzione switch può essere utilizzata per più diramazioni sulla base di un numero o una stringa:

- -
switch(action) {
-    case 'draw':
-        drawit();
-        break;
-    case 'eat':
-        eatit();
-        break;
-    default:
-        donothing();
-}
-
- -

Se non viene inserita l'istruzione break, l'esecuzione "naufragherà" nel prossimo livello. Questo è raramente il risultato voluto — in realtà vale la pena in particolare inserire un etichettatura deliberatamente con un commento, se vi vuole aiutare il debug:

- -
switch(a) {
-    case 1: // fallthrough
-    case 2:
-        eatit();
-        break;
-    default:
-        donothing();
-}
-
- -

La clausula default è opzionale. Si possono avere espressioni sia nello switch sia che nel case se si vuole; i confronti avvengono tra i due con l'operatore ===:

- -
switch(1 + 3) {
-    case 2 + 2:
-        yay();
-        break;
-    default:
-        neverhappens();
-}
-
- -

Oggetti

- -

Gli oggetti JavaScript sono semplicemente collezioni di coppie nome-valore. Come tali, essi sono simili a:

- - - -

Il fatto che questa struttura dati è così diffusa è la prova della sua versatilità. Dal momento che tutto (barra i tipi base) in JavaScript è un oggetto, qualunque programma JavaScript implica naturalmente un grande ricorso alla ricerca nelle tabelle hash. E' buona cosa che siano così veloci!

- -

La parte "name" è una stringa JavaScript, mentre il valore può essere qualunque valore JavaScript — incluso più oggetti. Questo permette di costruire strutture dati di complessità arbitraria.

- -

Ci sono due modalità di base per creare un oggetto vuoto:

- -
var obj = new Object();
-
- -

E:

- -
var obj = {};
-
- -

Entrambe sono semanticamente equivalenti; la seconda è chiamata sintassi letterale dell'oggetto, ed è più conveniente. Questa sintassi è anche la base del formato JSON e dovrebbe essere preferita ogni volta.

- -

Una volta creato si può accedere alle proprietà di un oggetto in una o due modalità:

- -
obj.name = "Simon";
-var name = obj.name;
-
- -

E...

- -
obj["name"] = "Simon";
-var name = obj["name"];
-
- -

Anche queste sono semanticamente equivalenti. Il secondo metodo ha il vantaggio che il nome della proprietà viene fornito come stringa, che significa che può essere calcolato durante l'esecuzione e l'utilizzo di questo metodo evita che siano applicate ottimizzazioni del motore JavaScript e minifier. Può essere inoltre usato per impostare o ottenere proprietà con nomi che sono parole riservate:

- -
obj.for = "Simon"; // Syntax error, because 'for' is a reserved word
-obj["for"] = "Simon"; // works fine
-
- -

La sintassi dell'oggetto letterale può essere usata per inizializzare un oggetto nella sua interezza:

- -
var obj = {
-    name: "Carrot",
-    "for": "Max",
-    details: {
-        color: "orange",
-        size: 12
-    }
-}
-
- -

Attributi di accesso possono essere concatenati:

- -
> obj.details.color
-orange
-> obj["details"]["size"]
-12
-
- -

Array (matrici)

- -

Gli array in JavaScript sono un tipo speciale di oggetto. Essi funzionano in modo molto simile agli oggetti regolari (si può accedere alle proprietà numeriche solo usando la sintassi []) ma hanno una proprietà magica chiamata 'length'. Questa è sempre uno in più dell'indice massimo dell'array.

- -

Il vecchio metodo per creare un array è il seguente:

- -
> var a = new Array();
-> a[0] = "dog";
-> a[1] = "cat";
-> a[2] = "hen";
-> a.length
-3
-
- -

Una notazione più conveniente è l'utilizzo di una array letterale:

- -
> var a = ["dog", "cat", "hen"];
-> a.length
-3
-
- -

Lasciare una virgola finale al termine di un array letterale è incompatibile tra i browser, quindi non fatelo.

- -

Nota che array.length non è necessariamente il numero di elementi nell'array. Considera il seguente esempio:

- -
> var a = ["dog", "cat", "hen"];
-> a[100] = "fox";
-> a.length
-101
-
- -

Ricorda — la lunghezza dell'array è uno più dell'indice più alto.

- -

Se si interroga un indice dell'array inesistente, la risposta sarà undefined:

- -
> typeof a[90]
-undefined
-
- -

Se si prende in considerazione quanto sopra, è possibile scorrere un array utilizzando le istruzioni seguenti:

- -
for (var i = 0; i < a.length; i++) {
-    // Do something with a[i]
-}
-
- -

Questo è un po' inefficiente, poichè si ricerca la proprietà length una volta ogni ciclo. Un possibile miglioramento è questo:

- -
for (var i = 0, len = a.length; i < len; i++) {
-    // Do something with a[i]
-}
-
- -

Un modo ancora più simpatico è questo:

- -
for (var i = 0, item; item = a[i++];) {
-    // Do something with item
-}
-
- -

Qui si stanno impostando due variabili. L'assegnamento nella parte centrale del ciclo for è anche verificato per veridicità — se ha successo, il ciclo continua. Siccome i viene incrementato ogni volta, gli elementi dalla matrice saranno assegnati all'elemento in ordine sequenziale. Il ciclo termina quando viene trovato un elemento "falso" (come un undefined).

- -

Nota che questo trucco dovrebbe essere usato solo per gli array che sappiamo non contengano valori "falsi" (array di oggetti o nodi del DOM per esempio). Se si effettua l'iterazione dei dati numerici che potrebbero includere uno 0, o dati stringa che potrebbero includere la stringa vuota, è necessario utilizza l'idioma i, len in sostituzione.

- -

Un altro modo per iterare è di utilizzare il ciclo for...in. Nota che se vengono aggiunte nuove proprietà all' Array.prototype, saranno anch'esse iterate da questo ciclo:

- -
for (var i in a) {
-  // Do something with a[i]
-}
-
- -

Se si vuole accodare un elemento all'array, la maniera più sicura per farlo è questa:

- -
a[a.length] = item;                 // same as a.push(item);
-
- -

Poichè a.length è uno in più dell'indice più alto, si può essere sicuri che l'elemento sarà assegnato ad una posizione vuota alla fine dell'array.

- -

Gli arrays nascono con alcuni metodi:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method nameDescription
a.toString()
a.toLocaleString()
a.concat(item[, itemN])Restituisce un nuovo array con gli elementi aggiunti ad esso.
a.join(sep)
a.pop()Rimuove e restituisce l'ultimo elemento.
a.push(item[, itemN])Push aggiunge uno o più elementi alla fine.
a.reverse()
a.shift()
a.slice(start, end)Restituisce un sub-array.
a.sort([cmpfn])Riceve una funzione di comparazione opzionale.
a.splice(start, delcount[, itemN])Permette di modificare un array cancellando una sezione e sostituendola con più elementi.
a.unshift([item])Antepone elementi all'inizio dell'array
- -

Funzioni

- -

Insieme con gli oggetti, le funzioni sono la componente principale nella comprensione di JavaScript. La funzione più elementare non potrebbe essere molto più semplice:

- -
function add(x, y) {
-    var total = x + y;
-    return total;
-}
-
- -

Ciò dimostra tutto quello che c'è da sapere sulle funzioni di base. Una funzione JavaScript può ricevere 0 (zero) o più parametri. Il corpo della funzione può contenere tutte le istruzioni che si desidera, e può dichiarare le proprie variabili che saranno locali alla stessa. L'istruzione return può essere usata per restituire un valore in qualsiasi momento, terminando la funzione. Se non viene utilizzata l'istruzione return (oppure viene restituito un valore vuoto o indefinito), JavaScript restituisce undefined.

- -

I parametri denominati risultano più simili alle linee guida di ogni altra cosa. È possibile chiamare una funzione senza passare i parametri che si aspetta, nel qual caso saranno impostati su undefined.

- -
> add()
-NaN // You can't perform addition on undefined
-
- -

È anche possibile passare più argomenti di quelli che la funzione si aspetta:

- -
> add(2, 3, 4)
-5 // added the first two; 4 was ignored
-
- -

Questo può sembrare un po' sciocco, ma le funzioni hanno accesso a una variabile aggiuntiva all'interno del loro corpo chiamata argomenti, che è un oggetto simil array che detiene tutti i valori passati alla funzione. Riscriviamo la funzione somma per ricevere tutti i valori che vogliamo:

- -
function add() {
-    var sum = 0;
-    for (var i = 0, j = arguments.length; i < j; i++) {
-        sum += arguments[i];
-    }
-    return sum;
-}
-
-> add(2, 3, 4, 5)
-14
-
- -

Questo, però, non è realmente più utile che scrivere 2 + 3 + 4 + 5. Creiamo una funzione per il calcolo della media:

- -
function avg() {
-    var sum = 0;
-    for (var i = 0, j = arguments.length; i < j; i++) {
-        sum += arguments[i];
-    }
-    return sum / arguments.length;
-}
-> avg(2, 3, 4, 5)
-3.5
-
- -

Questa è piuttosto utile, ma introduce un nuovo problema. La funzione avg() riceve una lista di argomenti separati da una virgola — ma cosa succede se si vuole trovare la media di un array? Si potrebbe semplicemente riscrivere la funzione come segue:

- -
function avgArray(arr) {
-    var sum = 0;
-    for (var i = 0, j = arr.length; i < j; i++) {
-        sum += arr[i];
-    }
-    return sum / arr.length;
-}
-> avgArray([2, 3, 4, 5])
-3.5
-
- -

Ma sarebbe bello essere in grado di riutilizzare la funzione che abbiamo già creato. Fortunatamente, JavaScript permette di chiamare una funzione e di chiamarla con un array arbitrario di argomenti, usando il metodo apply() di qualunque oggetto di funzione.

- -
> avg.apply(null, [2, 3, 4, 5])
-3.5 is the array to use as arguments; the first will be discussed later on. This emphasizes the fact that functions are objects too.
-
- -

JavaScript permette la creazione di funzioni anonime.

- -
var avg = function() {
-    var sum = 0;
-    for (var i = 0, j = arguments.length; i < j; i++) {
-        sum += arguments[i];
-    }
-    return sum / arguments.length;
-}
-
- -

Questa è semanticamente equivalente alla forma function avg(). Essa è estremamente potente, in quando consente di definire una funzione ovunque si possa normalmente inserire un espressione. Questo consente ogni sorta di trucco intelligente. Ecco un modo di "nascondere" alcune variabili locali - come in un ambito di blocco in C:

- -
> var a = 1;
-> var b = 2;
-> (function() {
-    var b = 3;
-    a += b;
-})();
-> a
-4
-> b
-2
-
- -

JavaScript consente di chiamare le funzioni in modo ricorsivo. Ciò è particolarmente utile per affrontare le strutture ad albero, come ad esempio nel DOM del browser.

- -
function countChars(elm) {
-    if (elm.nodeType == 3) { // TEXT_NODE
-        return elm.nodeValue.length;
-    }
-    var count = 0;
-    for (var i = 0, child; child = elm.childNodes[i]; i++) {
-        count += countChars(child);
-    }
-    return count;
-}
-
- -

Questo mette in evidenza un potenziale problema con le funzioni anonime: come fare a richiamarle ricorsivamente se non hanno un nome? La risposta si trova con l'oggetto arguments, che oltre ad agire come una lista di argomenti, fornisce anche una propietà chiamata arguments.callee. L'uso della arguments.callee è deprecato e anche disabilitato nel modo strict (rigoroso). In sostituzione si devono utilizzare le "funzioni anonime nominate" come di seguito:

- -
var charsInBody = (function counter(elm) {
-    if (elm.nodeType == 3) { // TEXT_NODE
-        return elm.nodeValue.length;
-    }
-    var count = 0;
-    for (var i = 0, child; child = elm.childNodes[i]; i++) {
-        count += counter(child);
-    }
-    return count;
-})(document.body);
-
- -

Il nome fornito a una funzione anonima come sopra è (o almeno dovrebbe essere) disponibile solo nell'ambito stesso della funzione. Questo consente sia più ottimizzazioni da svolgere da parte del motore sia un codice più leggibile.

- -

Oggetti personalizzati

- -
Nota: Per una discussione più dettagliata della programmazione orientata agli oggetti, vedi Introduzione a JavaScript Orientato agli Oggetti.
- -

Nella programmazione Object Oriented classica, gli oggetti sono collezioni di dati e metodi che operano su quei dati. JavaScript è un linguaggio basato su prototipi e non contiene l'istruzione classe, così come si trova in C++ o Java. (Questo a volte è fonte di confusione per i programmatori abituati ai linguaggi con una dichiarazione di classe.) Al suo posto, JavaScript usa le funzioni come classi. Consideriamo un oggetto persona con i campi nome e cognome. Ci sono due modi di visualizzare il nominativo: come  "nome cognome" o come "cognome, nome". Usando le funzioni e gli oggetti che abbiamo visto in precedenza, ecco un modo di ottenere il risultato voluto:

- -
function makePerson(first, last) {
-    return {
-        first: first,
-        last: last
-    }
-}
-function personFullName(person) {
-    return person.first + ' ' + person.last;
-}
-function personFullNameReversed(person) {
-    return person.last + ', ' + person.first
-}
-> s = makePerson("Simon", "Willison");
-> personFullName(s)
-Simon Willison
-> personFullNameReversed(s)
-Willison, Simon
-
- -

Questo funziona, ma è piuttosto brutto. Si finisce con dozzine di funzioni nel namespace globale. Ciò di cui abbiamo veramente bisogno è un modo per associare una funzione ad un oggetto. Dal momento che le funzioni sono oggetti, questo è facile:

- -
function makePerson(first, last) {
-    return {
-        first: first,
-        last: last,
-        fullName: function() {
-            return this.first + ' ' + this.last;
-        },
-        fullNameReversed: function() {
-            return this.last + ', ' + this.first;
-        }
-    }
-}
-> s = makePerson("Simon", "Willison")
-> s.fullName()
-Simon Willison
-> s.fullNameReversed()
-Willison, Simon
-
- -

Vi è qualcosa che non abbiamo visto prima: la parola chiave 'this'. Usata dentro una funzione, 'this' si riferisce all'oggetto corrente. Che cosa significa in realtà è specificato dal modo in cui è stata chiamata tale funzione. Se è stata chiamata usando la notazione col punto o la notazione con le parentesi su un oggetto, questo oggetto diventa 'this'. Se la notazione col punto non è stata usata per la chiamata, 'this' si riferisce all'oggetto globale. Questa è una causa di errori frequente. Ad esempio:

- -
> s = makePerson("Simon", "Willison")
-> var fullName = s.fullName;
-> fullName()
-undefined undefined
-
- -

Quando chiamiamo fullName(), 'this' è legata all'oggetto globale. Dato che non ci sono variabili globali chiamate first o last riceviamo undefined per ognuna delle due.

- -

Possiamo prendere il vantaggio della parola chiave 'this' per migliorare la nostra funzione makePerson:

- -
function Person(first, last) {
-    this.first = first;
-    this.last = last;
-    this.fullName = function() {
-        return this.first + ' ' + this.last;
-    }
-    this.fullNameReversed = function() {
-        return this.last + ', ' + this.first;
-    }
-}
-var s = new Person("Simon", "Willison");
-
- -

Abbiamo introdotto un'altra parola chiave: 'new'. new è fortemente correlata a 'this'. Quello che fa è creare un oggetto vuoto nuovo di zecca e quindi chiamare la funzione specificata, con 'this' impostato sul nuovo oggetto. Le funzioni che sono disegnate per essere richiamate dalla 'new' sono chiamate costruttori. La pratica comune è di nominare queste funzioni con la prima lettera maiuscola in modo da ricordarsi di chiamarle con il new.

- -

I nostri oggetti persona stanno migliorando, ma vi sono ancora alcuni lati brutti in loro. Ogni volta che si crea un oggetto persona, stiamo creando due nuovi oggetti funzione all'interno di esso - non sarebbe meglio se il codice fosse stato condiviso?

- -
function personFullName() {
-    return this.first + ' ' + this.last;
-}
-function personFullNameReversed() {
-    return this.last + ', ' + this.first;
-}
-function Person(first, last) {
-    this.first = first;
-    this.last = last;
-    this.fullName = personFullName;
-    this.fullNameReversed = personFullNameReversed;
-}
-
- -

Così va meglio: stiamo creando i metodi della funzione una sola volta, e assegnando ad essi i riferimenti all'interno del costruttore. Possiamo fare di meglio? La risposta è sì:

- -
function Person(first, last) {
-    this.first = first;
-    this.last = last;
-}
-Person.prototype.fullName = function() {
-    return this.first + ' ' + this.last;
-}
-Person.prototype.fullNameReversed = function() {
-    return this.last + ', ' + this.first;
-}
-
- -

Person.prototype è un oggetto condiviso da tutte le istanze di Person. Essa fa parte di una catena di ricerca (che ha un nome speciale, "catena di prototipi"): ogni volta che si tenta di accedere ad una proprietà di Person che non è impostata, JavaScript controllerà Person.prototype per vedere se quella proprietà esiste al suo interno. Come risultato, qualsiasi valore assegnato a Person.prototype diventa disponibile a tutte le istanze del costruttore per mezzo dell'oggetto this.

- -

Si tratta di uno strumento incredibilmente potente. JavaScript consente di modificare il prototipo di qualcosa in qualsiasi momento nel programma, il che significa che è possibile aggiungere metodi extra per gli oggetti esistenti in fase di esecuzione:

- -
> s = new Person("Simon", "Willison");
-> s.firstNameCaps();
-TypeError on line 1: s.firstNameCaps is not a function
-> Person.prototype.firstNameCaps = function() {
-    return this.first.toUpperCase()
-}
-> s.firstNameCaps()
-SIMON
-
- -

È interessante notare che è anche possibile aggiungere le cose al prototipo degli oggetti nativi JavaScript. Aggiungiamo un metodo a String che restituisca la stringa al contrario:

- -
> var s = "Simon";
-> s.reversed()
-TypeError on line 1: s.reversed is not a function
-> String.prototype.reversed = function() {
-    var r = "";
-    for (var i = this.length - 1; i >= 0; i--) {
-        r += this[i];
-    }
-    return r;
-}
-> s.reversed()
-nomiS
-
- -

Il nostro nuovo metodo funziona anche con le stringhe letterali!

- -
> "This can now be reversed".reversed()
-desrever eb won nac sihT
-
- -

Come detto prima, il prototipo fa parte di una catena. La radice di questa catena è Object.prototype, i cui metodi includono toString() — è questo metodo che viene chiamato quando si tenta di rappresentare un oggetto come una stringa. Questo è utile per verificare il nostro oggetto Person:

- -
> var s = new Person("Simon", "Willison");
-> s
-[object Object]
-> Person.prototype.toString = function() {
-    return '<Person: ' + this.fullName() + '>';
-}
-> s
-<Person: Simon Willison>
-
- -

Ricordate come avg.apply() aveva un primo argomento nullo? Possiamo riesaminarlo adesso. Il primo argomento di apply() è l'oggetto che dovrebbe essere trattato come 'this'. Per esempio, qui una semplice implementazione di 'new':

- -
function trivialNew(constructor) {
-    var o = {}; // Create an object
-    constructor.apply(o, arguments);
-    return o;
-}
-
- -

Questa non è un'esatta replica di new in quanto non imposta la catena del prototipo (sarebbe difficile da illustrare). Non è una cosa che si usa molto spesso, ma è utile conoscerla. In questo snippet, ...args (puntini inclusi) è chiamato il "rest arguments" – come indicato dal nome, e contiene il resto degli argomenti. Per ora, questa "feature" è sperimentale e solo disponibile in Firefox; è raccomandato attaccare gli arguments per ora.

- -

Chiamare

- -
var bill = trivialNew(Person, "William", "Orange");
- -
- -

è dunque quasi equivalente a

- -
var bill = new Person("William", "Orange");
- -
- -

apply() ha una funzione sorella dal nome call, che di nuovo ti consente di impostare 'this' ma prende una lista espansa di argomenti invece che un array.

- -
function lastNameCaps() {
-    return this.last.toUpperCase();
-}
-var s = new Person("Simon", "Willison");
-lastNameCaps.call(s);
-// Is the same as:
-s.lastNameCaps = lastNameCaps;
-s.lastNameCaps();
-
- -

Inner functions

- -

In JavaScript è consentito dichiarare una funzione all'interno di un'altra funzione. Lo abbiamo già visto prima, nel caso della precedente funzione makePerson(). Un dettaglio importante di funzioni innestate in JavaScript è che esse possono accedere alle variabili della funzione di livello superiore:

- -
function betterExampleNeeded() {
-    var a = 1;
-    function oneMoreThanA() {
-        return a + 1;
-    }
-    return oneMoreThanA();
-}
-
- -

Ciò è di grande utilità per scrivere codice più manutenibile. Se una funzione dipende da una o due altre funzioni che non sono usate in nessuna altra parte del tuo codice, è possibile nidificare quelle funzioni di utilità dentro la funzione che sarà chiamata dall'esterno. Questo riduce il numero di funzioni che si trovano nel "global scope", che è sempre una buona cosa.

- -

Questa è anche una grande cosa contro il richiamo di variabili globali. Quando si scrive codice complesso si è spesso tentati di usare variabili globali per condividere i valori tra più funzioni — e ciò rende il codice difficile da manutenere. Le funzioni nidificate possono condividere le variabili della funzione padre, così è possibile usare questo meccanismo per accoppiare le funzioni quando serve, senza contaminare il tuo namespace globale — rendi locali le variabili globali per piacere. Questa tecnica dovrebbe essere usata con parsimonia, ma è una capacità utile da avere.

- -

Closures

- -

Questo ci porta ad una delle più potenti astrazioni che JavaScript ha da offrire — ma anche quella che può generare più confusione. Cosa fa questo codice sotto?

- -
function makeAdder(a) {
-    return function(b) {
-        return a + b;
-    }
-}
-x = makeAdder(5);
-y = makeAdder(20);
-x(6)
-?
-y(7)
-?
-
- -

Il nome della funzione makeAdder dovrebbe essere esplicito: essa può creare delle nuove funzioni 'adder', che, se chiamate con un determinato argomento, lo addizionano all'argomento con il quale sono state create.

- -

Quello che sta avvenendo qui è praticamente la stessa cosa vista precedentemente con le "inner functions": una funzione definita dentro un'altra funzione ha accesso alle variabili della funzione esterna. La sola differenza è che in questo caso la funzione esterna ha già restituito il suo risultato, e quindi il senso comune sembrerebbe indicare che le sue variabili locali non siano più disponibili. Ma esse esistono ancora — altrimenti le funzioni "adder" non sarebbero capaci di lavorare. Quello che c'è di più è che ci sono due "copie" differenti delle variabili locali di makeAdder — una nella quale a è 5 e una nella quale a è 20. Così il risultato di quelle chiamate di funzione è il seguente:

- -
x(6) // returns 11
-y(7) // returns 27
-
- -

Ecco cosa sta effettivamente avvenendo. Quando JavaScript esegue una funzione, viene creato un oggetto con il proprio ambito di visibilità ('scope object') per trattenere le variabili locali di quella funzione. Esso è inizializzato con tutte le variabili passate in ingresso alla funzione come parametri. Ciò è simile all'oggetto globale in cui si trovano tutte le variabili globali e le funzioni, ma con una paio di differenze importanti: primo, un nuovo 'scope object' etichettato è creato ogni volta che una funzione inizia l'esecuzione, e secondo, a differenza dell'oggetto globale (che nei bowser è accessibile come 'window') non si può accedere direttamente a questi 'scope object' dal tuo codice JavaScript. Ad esempio non c'è nessun meccanismo per iterare sulle proprietà dello 'scope object' corrente.

- -

Quindi, quando makeAdder è chiamato viene creato un oggetto scope con una proprietà: a, che è l'argomento passato alla funzione makeAdder . A questo punto makeAdder restituisce quindi una funzione appena creata. Normalmente il raccoglitore di rifiuti  di JavaScript eliminerebbe l'oggetto scope creato per makeAdder , ma la funzione restituita mantiene un riferimento a tale oggetto scope. Di conseguenza l'oggetto scope non verrà eliminato finchè non ci saranno più riferimenti all'oggetto che la funzione makeAdder restituisce.

- -

Gli oggetti scope formano una catena chiamata 'scope chain', simile alla catena di prototipi, 'prototype chain', del sistema a oggetti di JavaScript.

- -

Una closure è la combinazione di una funzione e dell'oggetto scope in cui è stata creata.

- -

Le closures ti consentono di salvare lo stato e in quanto tali, possono spesso essere utilizzate al posto degli oggetti. Puoi trovare alcune eccellenti introduzioni alle closures (in lingua inglese).

- -

Memory leaks

- -
 Uno sfortunato effetto collaterale delle chiusure è il rendere facile perdere memoria
- su Internet Explorer. JavaScript alloca gli oggetti nella memoria al momento della loro
- creazione e tale memoria viene recuperata dal browser quando non rimangono riferimenti a un
- oggetto.
- Gli oggetti forniti dall'host vengono gestiti da quell'ambiente.
-
- Gli host del browser devono gestire un gran numero di oggetti che rappresentano
- la pagina HTML presentata: gli oggetti del DOM. Spetta al browser gestire l'assegnazione e
- il recupero di questi.
-
- Internet Explorer utilizza il proprio schema di raccolta dei rifiuti per questo,
- separato dal meccanismo utilizzato da JavaScript.
- È l'interazione tra i due che può causare perdite di memoria.
-
-Una perdita di memoria in IE si verifica ogni volta che viene formato un riferimento circolare
-tra un oggetto JavaScript e un oggetto nativo. Considera quanto segue:
- -
function leakMemory() {
-    var el = document.getElementById('el');
-    var o = { 'el': el };
-    el.o = o;
-}
-
- -

Il riferimento circolare formato sopra crea una perdita di memoria;

- -

IE non libererà la memoria utilizzata da el fino al completo riavvio del browser. Il caso di cui sopra rischia di passare inosservato; le perdite di memoria diventano un problema reale solo nelle applicazioni a esecuzione prolungata o nelle applicazioni che perdono grandi quantità di memoria a causa di grandi strutture di dati o schemi di perdite all'interno dei loop. Le perdite sono raramente così ovvie: spesso la struttura dei dati trapelati può avere molti livelli di riferimenti, oscurando il riferimento circolare. Le chiusure rendono facile creare una perdita di memoria senza volerlo. Considera questo:

- -
function addHandler() {
-    var el = document.getElementById('el');
-    el.onclick = function() {
-        this.style.backgroundColor = 'red';
-    }
-}
-
- -

Il codice precedente imposta l'elemento in modo che diventi rosso quando viene cliccato. Crea anche una perdita di memoria. Perché? Perché il riferimento a el è inavvertitamente catturato nella chiusura creata per la funzione interna anonima. Questo crea un riferimento circolare tra un oggetto JavaScript (la funzione) e un oggetto nativo (el).

- -
needsTechnicalReview();
-
- -

Esistono numerose soluzioni per questo problema. Il più semplice è non usare la variabile el:

- -
function addHandler(){
-    document.getElementById('el').onclick = function(){
-        this.style.backgroundColor = 'red';
-    }
-}
-
- -

Sorprendentemente, un trucco per rompere i riferimenti circolari introdotti da una chiusura è aggiungere un'altra chiusura:

- -
function addHandler() {
-    var clickHandler = function() {
-        this.style.backgroundColor = 'red';
-    };
-    (function() {
-        var el = document.getElementById('el');
-        el.onclick = clickHandler;
-    })();
-}
-
- -

La funzione interna viene eseguita immediatamente, e nasconde il suo contenuto dalla chiusura creata con clickHandler. Un altro buon trucco per evitare le chiusure è rompere i riferimenti circolari durante l'evento window.onunload. Molte librerie di eventi lo faranno per te. Nota che così facendo si disabilita bfcache in Firefox 1.5, quindi non dovresti registrare un listener di scaricamento in Firefox, a meno che tu non abbia altri motivi per farlo.

- -
-

Original Document Information

- - -
-- cgit v1.2.3-54-g00ecf