diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:17 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:17 -0500 |
commit | da78a9e329e272dedb2400b79a3bdeebff387d47 (patch) | |
tree | e6ef8aa7c43556f55ddfe031a01cf0a8fa271bfe /files/it/web/javascript/guida | |
parent | 1109132f09d75da9a28b649c7677bb6ce07c40c0 (diff) | |
download | translated-content-da78a9e329e272dedb2400b79a3bdeebff387d47.tar.gz translated-content-da78a9e329e272dedb2400b79a3bdeebff387d47.tar.bz2 translated-content-da78a9e329e272dedb2400b79a3bdeebff387d47.zip |
initial commit
Diffstat (limited to 'files/it/web/javascript/guida')
9 files changed, 3906 insertions, 0 deletions
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 new file mode 100644 index 0000000000..76e72f5cba --- /dev/null +++ b/files/it/web/javascript/guida/controllo_del_flusso_e_gestione_degli_errori/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 +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Grammar_and_types", "Web/JavaScript/Guide/Loops_and_iteration")}}</div> + +<p class="summary">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.</p> + +<p>Il <a href="/en-US/docs/Web/JavaScript/Reference/Statements">JavaScript reference</a> contiene dettagli esaustivi sulle istruzioni di questo capitolo. Il carattere punto e virgola (<code>;</code>) è usato per separare le varie istruzioni del codice JavaScript.</p> + +<p>Ogni espressione JavaScript è a sua volta un'istruzione. Si veda a riguardo <a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators">Espressioni ed operatori</a> per una completa descrizione delle espressioni.</p> + +<h2 id="Costrutto_di_blocco">Costrutto di blocco</h2> + +<p>Un costrutto fondamentale è il <strong>blocco</strong>, usato per raggruppare insieme più istruzioni, delimitato da un paio di parentesi graffe ({}):</p> + +<pre class="syntaxbox notranslate">{ + istruzione_1; + istruzione_2; + . + . + . + istruzione_n; +} +</pre> + +<h3 id="Esempi"><strong>Esempi</strong></h3> + +<p>Il blocco è comunemente usato assieme alle istruzioni per il controllo del flusso (e.g. <code>if</code>, <code>for</code>, <code>while</code>).</p> + +<pre class="brush: js notranslate">while (x < 10) { + x++; +} +</pre> + +<p>Qui, <code>{ x++; }</code> rappresenta un blocco.</p> + +<p><strong>Importante</strong>: JavaScript prima di ECMAScript2015 <strong>non</strong> 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:</p> + +<pre class="brush: js notranslate">var x = 1; +{ + var x = 2; +} +console.log(x); // produce 2 +</pre> + +<p>Risulta 2 perché l'istruzione di definizione <code>var x</code> dentro il blocco ha lo stesso campo di visibilità dell'istruzione <code>var x</code> al di fuori del blocco. Mentre in C o Java, il codice equivalente avrebbe prodotto 1.</p> + +<p>A partire da ECMAScript2015, la dichiarazione di variabile con l'istruzione <code>let</code> ha visibilità di blocco. Si veda il riferimento a {{jsxref("Statements/let", "let")}} per ulteriori informazioni.</p> + +<h2 id="Costrutti_Condizionali">Costrutti Condizionali</h2> + +<p>Un costrutto condizionale è un insieme di istruzioni che vengono eseguite se una specifica condizione risulta vera. JavaScript prevede due costrutti condizionali: <code>if...else</code> e <code>switch</code>.</p> + +<h3 id="Costrutto_if...else"><code>Costrutto if...else</code></h3> + +<p>Si usa il costrutto <code>if</code> per eseguire un blocco di istruzioni se una condizione logica è vera. Si usa la clausola opzionale <code>else</code> per eseguire istruzioni nel caso in cui la stessa condizione sia falsa. Un costrutto <code>if...else</code> si presenta come qui sotto:</p> + +<pre class="brush: js notranslate">if (condizione) { + istruzioni_se_vera_la_condizione; +} else {// opzionale + istruzioni_se_falsa_la_condizione; +}</pre> + +<p>Qui la <code>condizione</code> è qualsiasi espressione che sia valutabile come vera oppure falsa (<code>true</code> o <code>false</code>). Si veda il riferimento a <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean#Description">Boolean</a> per una spiegazione su cosa possa essere valutabile come <code>true</code> o <code>false</code>. Se la <code>condizione</code> viene valutata <em>true</em>, <code>istruzioni_se_vera_la_condzione</code> verrà eseguito, altrimenti verrà eseguito <code>istruzioni_se_falsa_la_condzione</code>. <code>istruzioni_se_vera_la_condzione</code> e <code>istruzioni_se_falsa_la_condzione</code> possono essere qualsiasi istruzione, incluso un altro <code>if</code>.</p> + +<p>Si possono pure combinare le istruizioni <code>else if</code> per testare molteplici condizioni in sequenza, come il seguente codice dimostra:</p> + +<pre class="syntaxbox notranslate">if (condizione_1) { + istruzione_1; +} else if (condizione_2) { + istruzione_2; +} else if (condizione_n) { + istruzione_n; +} else { + ultima_istruzione; +} +</pre> + +<p>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 (<code>{ ... }</code>) . In generale è buona pratica usare un blocco specialmente se si usano <code>if</code> annidati:</p> + +<pre class="syntaxbox notranslate">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; + ... +} +</pre> + +<div>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:</div> + +<div></div> + +<pre class="example-bad brush: js notranslate">if (x = y) {// questa è una assegnazione + /* istruzioni qui */ +}</pre> + +<p>Se si deve proprio usare un assegnamento in una espressione condizionale è pratica comune aggiungere un paio di parentesi tonde attorno all'assegnamento. Per esempio:</p> + +<pre class="brush: js notranslate">if ((x = y)) { + /* istruzioni qui */ +} +</pre> + +<h4 id="Valori_valutabili_a_false">Valori valutabili a false</h4> + +<p>I seguenti valori si valutano a <code>false</code> (sono anche detti {{Glossary("Falsy")}} value):</p> + +<ul> + <li><code>false</code></li> + <li><code>undefined</code></li> + <li><code>null</code></li> + <li><code>0</code></li> + <li><code>NaN</code></li> + <li>la stringa vuota (<code>""</code>)</li> +</ul> + +<p>Tutti gli altri valori, inclusi gli oggetti, saranno valutati a <code>true</code> in una istruzione condizionale.</p> + +<p>Non si confonda il valori primitivi booleani <code>true</code> e <code>false</code> con i valori <code>true</code> e <code>false</code> dell'oggetto {{jsxref("Boolean")}}. Ad esempio:</p> + +<pre class="brush: js notranslate">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 +</pre> + +<h4 id="Esempi_2"><strong>Esempi</strong></h4> + +<p>Nell'esempio a seguire la funzione <code>controllaDati</code> ritorna <code>true</code> se il numero di caratteri contenuti nella proprietà <code>value</code> dell'oggetto <code>Text (treCaratteri)</code> è tre, altrimenti mostra un popup di alert e, infine, ritorna il valore <code>false</code>.</p> + +<pre class="brush: js notranslate">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; + } +} +</pre> + +<h3 id="Costrutto_switch"><code>Costrutto switch</code></h3> + +<p>Un costrutto <code>switch</code> 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 <code>case</code>. Se si incontra una corrisopondenza il programma eseguirà le istruzioni associate. Un costrutto <code>switch</code> si presenta come nell'esempio qui sotto riportato:</p> + +<pre class="syntaxbox notranslate">switch (espressione) { + case etichetta_1: + istruzione_1 + [break;]// opzionale + case etichetta_2: + istruzione_2 + [break;] + ... + default: + istruzioni_di_default + [break;] +} +</pre> + +<p>Il programma cerca la prima corrispondenza tra il valore ottentuto della valutazione dell'<code>espressione </code>e l'etichetta nella clausola <code>case</code>, 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 <code>default</code> e, se la trova, esegue le istruizioni ad essa relative. Se non è stata data alcuna clausola <code>default</code> il programma continuerà con l'istruzione successiva al blocco <code>switch</code>. La clausola <code>default</code> è l'ultima che appare nel blocco<code> switch</code>, ma questa è una convenzione non la regola.</p> + +<p>Il <code>break</code> opzionale, associato con ogni clausola <code>case,</code> assicura che il programma esca dal blocco <code>switch</code> una volta eseguite le istruzioni associate alla clausola e continui la sua esecuzione all'istruzione che segue il costrutto <code>switch</code>. Se il <code>break</code> è omesso il programma continua la sua esecuzione all'istruzione successiva nello stesso costrutto <code>switch</code>, ciò significa che eseguirà le istruzioni associate alla clausola <code>case/default</code> (se ci sono) successiva a quella appena terminata.</p> + +<h4 id="Esempi_3"><strong>Esempi</strong></h4> + +<p>Nel seguente esempio, se la variabile <code>tipidifrutto</code> contiene "Banane", il programma cercherà la corrispondente clausola <code>case "Banane"</code> ed eseguirà le istruzioni associate. Quando incontra il <code>break</code>, il porgramma esce dallo <code>switch</code> ed esegue l'istruzione successiva al blocco di <code>switch</code>. Se, invece, il <code>break</code> fosse stato omesso le istuzioni collegate con la clausola <code>case "Ciliege"</code> sarebbero state eseguite.</p> + +<pre class="brush: js notranslate">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?");</pre> + +<h2 id="Costrutti_di_gestione_delle_Eccezioni">Costrutti di gestione delle Eccezioni</h2> + +<p>Si può sollevare/generare un'eccezione attraverso l'istruzione <code>throw</code> e si possono gestire usando il costrutto <code>try...catch</code>.</p> + +<ul> + <li><a href="#Istruzione_throw">istruzione throw</a></li> + <li><a href="#trt_catch">costrutto try...catch</a></li> +</ul> + +<h3 id="Tipi_di_eccezione">Tipi di eccezione</h3> + +<p>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:</p> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects#Fundamental_objects">eccezioni di ECMAScript</a></li> + <li>{{domxref("DOMException")}} e {{domxref("DOMError")}}</li> +</ul> + +<h3 id="Istruzione_throw_2"><code><a id="Istruzione_throw" name="Istruzione_throw"></a>Istruzione throw</code></h3> + +<p>Si usa l'istruzione <code>throw</code> per sollevare/generare un'eccezione. Quando si genera un'eccezione va specificata un'espressione che produca un valore da usarsi come eccezione:</p> + +<pre class="syntaxbox notranslate">throw espressione; +</pre> + +<p>Si può usare una qualsiasi espressione con l'istruzione <code>throw </code>e non solamente espressioni di un certo tipo. Il seguente pezzo di codice lo dimostra:</p> + +<pre class="brush: js notranslate">throw "Errore2"; // tipo String +throw 42; // tipo Number +throw true; // tipo Boolean +throw {toString: function() { return "Sono un oggetto!"; } }; +</pre> + +<div class="note"><strong>Note:</strong> Si può specificare un oggetto quando si genera un'eccezione. Si può poi far riferimento alle proprietà dell'oggetto nel blocco <code>catch</code>. Il seguente esempio crea un oggetto <code>myUserException</code> del tipo <code>UserException</code> e lo usa nell'istruzione throw.</div> + +<pre class="brush: js notranslate">// 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!);</pre> + +<h3 id="Costrutto_try...catch_..._finally"><code><a id="trt_catch" name="trt_catch"></a>Costrutto try...catch (... finally)</code></h3> + +<p>Il costrutto <code>try...catch</code> 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 <code>try...catch</code> la cattura.</p> + +<p>Il costrutto <code>try...catch</code> è costituito da un blocco <code>try</code>, che contiene a sua volta uno o più istruzioni, e da al più (vedi nota più sotto) un blocco <code>catch</code>, contenenti istruzioni per gestire l'eccezione che eventulmente sarà sollevata all'interno del blocco <code>try</code>. Cioè si vorrebbe che il blocco <code>try</code> fosse eseguito senza errori, ma se non fosse possibile si vuole che l'esecuzione passi al blocco <code>catch</code>. Se un'istruzione contenuta nel blocco (o in una funzione chiamata all'interno del blocco) <code>try</code> genera un'eccezione, il controllo passa immediatamente al blocco <code>catch</code>. Se nessuna eccezione è sollevata all'interno del blocco <code>try</code>, il blocco <code>catch</code> è semplicemente ignorato. Il blocco <code>finally (</code>opzionale se c'è il blocco <code>catch</code>, ma necessario se manca quest'utimo) è eseguito subito dopo l'esecuzione dei blocchi <code>try<font face="Open Sans, Arial, sans-serif">/</font></code><code>catch</code>, ma prima di una qualsiasi istruzione che segua gli stessi <code>try...catch...finally</code>.</p> + +<div class="note"> +<p>In realtà il browser Firefox è in grado di suppostare i blocchi <code>catch</code> condizionati, oltre quello incondizionato, rendendo virtualmeente illimitata la definizione di più di un blocco <code>catch </code>per uno stesso blocco<code> try</code>. Tuttavia questa caratteristica non è standard e se ne scoraggia l'uso, si veda a proposito la referenza {{jsxref("Statements/try...catch", "try...catch")}}.</p> +</div> + +<p>L'esempio che segue usa il costrutto di <code>try...catch</code>. L'esempio chiama una funzione che ritorna il nome del mese estratto da un array grazie al parametro <code>mo</code> passato alla funzione. Se il valore passato non corrispondesse al numero di mese consentito (tra 1 e 12), un'eccezione verrebbe sollevata col valore <code>"numeroMeseNonValido"</code><code> </code>e il blocco <code>catch</code> assegnerebbe alla variabile <code>nomeDelMese</code> il vaore di "<code>sconoscuto"</code>.</p> + +<pre class="brush: js notranslate">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 +</pre> + +<h4 id="Il_blocco_catch">Il blocco <code>catch</code></h4> + +<p>Si può usare il blocco <code>catch</code> per gestire le eccezioni che possono essere generate nel blocco <code>try</code>.</p> + +<pre class="syntaxbox notranslate">catch (catchID) { + // istruzioni +} +</pre> + +<p>Il blocco <code>catch</code> viene specificato un identificatore (<code>catchID</code> nel precedente esempio) che conterrà il valore specificato nell'istruzione <code>throw.</code> Si può usare questo identificatore per ottenere informazione ulteriori circa l'eccezione che è stata generata. JavaScript crea questo identificatore quando si entra nel blocco <code>catch.</code> L'identificatore è valido solo per la durata in esecuzione del blocco <code>catch </code>stesso, infatti usciti dal blocco <code>catch</code> termina la sua esistenza e non è più disponibile.</p> + +<p>Per esempio, il seguente codice solleva un'eccezione. Quando l'eccezione si realizza il controllo passa al blocco <code>catch</code>.</p> + +<pre class="brush: js notranslate">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 +} +</pre> + +<h4 id="Il_blocco_finally">Il blocco <code>finally</code></h4> + +<p>Il blocco <code>finally</code> contiene istruzioni che vengono eseguite subito dopo i blocchi <code>try</code> ed eventualmente <code>catch</code>, ma prima di ogni altra istruzione che segua il costrutto <code>try...catch...finally</code>. Il blocco <code>finally</code> è eseguito indipendentemente dal fatto che un'eccezione sia o meno generata. Se un'eccezione viene sollevata le istruzioni nel blocco <code>finally</code> saranno eseguite anche se il blocco <code>catch</code> corrispondente la gestisce.</p> + +<p>Si può usare il blocco <code>finally</code> 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 <code>finally</code> chiude il file prima che lo script termini/fallisca.</p> + +<pre class="brush: js notranslate">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 +} +</pre> + +<p>Se il blocco <code>finally</code> ritorna un valore questo diviene il valore ritornato dall'intero costrutto <code>try-catch-finally</code> a dispetto di qualsiasi valore eventualmente ritornato dai blocchi <code>try/c</code><code>atch</code>:</p> + +<pre class="brush: js notranslate">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 +</pre> + +<p>La sovrascrittura dei valori di ritorno, da parte del blocco <code>finally,</code> colpisce anche le eccezioni generate e/o ri-generate dentro il blocco <code>catch</code>:</p> + +<pre class="brush: js notranslate">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"</pre> + +<h4 id="try...catch_innestati">try...catch innestati</h4> + +<p>Si possono annidare <code>try...catch.</code> Se un blocco <code>try...catch</code> interno non ha il blocco <code>catch </code>(in questo caso è d'obbligo che ci sia il blocco <code>finally</code>, anche vuoto, altrimenti si ha un errore sintattico), il blocco catch, del costrutto <code>try...catch</code> che lo racchiude, catturerà l'eventuale eccezione.</p> + +<pre class="brush: js notranslate">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"</pre> + +<h3 id="Utilizzo_degli_oggetti_Error">Utilizzo degli oggetti <code>Error</code></h3> + +<p>A seconda del tipo di errore se si è in grado di usare le proprietà '<code>name</code>' e '<code>message</code>' si può avere un messaggio più ricco. '<code>name</code>' fornisce la classe generale dell'Error (e.g., 'DOMException' o 'Error'), mentre '<code>message</code>' generalmente fornisce un messaggio più conciso rispetto al convertire l'oggetto corrispondente all'errore in una stringa.</p> + +<p>Se si crea una propria eccezione affiché ci si avvantaggi di queste proprietà (come nel caso, ad esempio, del blocco <code>catch</code> che non discrimini tra l'oggetto rappresentante la propria eccezione e quello di sistema) si può usare il costruttore dell'oggetto Error:</p> + +<pre class="brush: js notranslate">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) +}</pre> + +<h2 id="I_Promise">I Promise</h2> + +<p>A partire da ECMAScript2015, JavaScript acquisisce il supporto agli oggetti {{jsxref("Promise")}} permettendo di controllare l'esecuzione di operazioni in modo differito e asincrono.</p> + +<p>Un <code>Promise</code> può essere in uno di questi stati:</p> + +<ul> + <li><em>pending</em>: stato iniziale, non <em>fulfilled</em> o <em>rejected</em>.</li> + <li><em>fulfilled</em>: operazione risucita.</li> + <li><em>rejected</em>: operazione fallita.</li> + <li><em>settled</em>: il Promise è alternativamente <em>fulfilled</em> o <em>rejected</em>, ma non <em>pending</em>.</li> +</ul> + +<p><img alt="" src="https://mdn.mozillademos.org/files/8633/promises.png" style="height: 297px; width: 801px;"></p> + +<h3 id="Caricare_unimmagine_con_XHR">Caricare un'immagine con XHR</h3> + +<p>Un esempio di semplice utilizzo di un <code>Promise</code> e <code><a href="/en-US/docs/Web/API/XMLHttpRequest">XMLHttpRequest</a></code> per caricare un'immagine è disponibile nel repository <a href="https://github.com/mdn/promises-test/blob/gh-pages/index.html">promise-test</a> di MDN GitHub. Si può anche<a href="http://mdn.github.io/promises-test/"> vedere in azione</a>. 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 <code>Promise</code> per darti un'idea del suo funzionamento:</p> + +<pre class="brush: js notranslate">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(); + }); +}</pre> + +<p>Per informazioni più dettagliate si veda la pagina di riferimento relativa al {{jsxref("Promise")}}.</p> + +<div>{{PreviousNext("Web/JavaScript/Guide/Grammar_and_types", "Web/JavaScript/Guide/Loops_and_iteration")}}</div> diff --git a/files/it/web/javascript/guida/dettagli_object_model/index.html b/files/it/web/javascript/guida/dettagli_object_model/index.html new file mode 100644 index 0000000000..1e2d4dc74f --- /dev/null +++ b/files/it/web/javascript/guida/dettagli_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 +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Working_with_Objects", "Web/JavaScript/Guide/Iterators_and_Generators")}}</div> + +<div class="note"> +<p>Il contenuto di questo articolo è in discussione. Lascia un feedback e aiutaci a rendere migliore questa pagina: {{bug(1201380)}}.</p> +</div> + +<p class="summary">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.</p> + +<p>Questo capitolo presuppone una certa familiarità con JavaScript e con l'uso delle funzioni per la creazione di semplici oggetti.</p> + +<h2 id="Linguaggi_class-based_vs._linguaggi_prototype-based">Linguaggi class-based vs. linguaggi prototype-based</h2> + +<p>I linguaggi ad oggetti basati su classi, come Java e C++, si basano su due entità distinte: le classi (<em>classes</em>) e le istanze (<em>instances</em>).</p> + +<ul> + <li>Una <em>class</em>e definisce tutte le proprietà (considering methods and fields in Java, or members in C++, to be properties) che caratterizzano una determinata collezione di oggetti. Una classe è un'entità astratta, più che un membro del gruppo di oggetti che descrive. Per esempio, la classe <code>Employee</code> può rappresentare il gruppo di tutti i dipendenti.</li> + <li>Un'<em>istanza</em>, d'altra parte, è l'istanziazione di una classe; cioè uno dei suoi membri. Per esempio <code>Victoria</code> può essere un'istanza della classe <code>Employee</code>, che rappresenta un particolare individuo come un dipendente. Un'istanza ha esattamente le stesse proprietà della classe a cui appartiene (né più, né meno).</li> +</ul> + +<p>Un linguaggio basato su prototipi, come JavaScript, non fa questa distinzione: ha solo oggetti. Introduce la nozione di <em>oggetto prototipo</em> (<em>prototypical object</em>), 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 <em>prototipo</em>, consentendo al secondo oggetto di condividere le proprietà del primo.</p> + +<h3 id="Definizione_di_una_classe">Definizione di una classe</h3> + +<p>Nei linguaggi basati su classi, le classi vengono definite in <em>class definition</em> separate. In queste definizioni è possibile specificare metodi speciali, chiamari <em>costruttori</em> (<em>constructors</em>), 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 <em>new</em> associato al metodo costruttore.</p> + +<p>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 <em>new</em> associato a una funzione costruttore.</p> + +<h3 id="Sottoclassi_e_ereditarietà">Sottoclassi e ereditarietà</h3> + +<p>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 <em>sottoclasse</em> (<em>subclass</em>) 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 <code>Employee</code> include solo le proprietà <code>name</code> <code>e dept</code>, <code>e Manager</code> è una sottoclasse di <code>Employee</code> che aggiunge la proprietà <code>reports</code>. In questo caso, un'istanza della classe <code>Manager</code> avrà tutte e tre le proprietà: <code>name</code>, <code>dept</code>, <code>e reports</code>.</p> + +<p>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 <code>Employee</code>, specificando le proprietà <code>name</code> <code>e dept</code>. In seguito, si definisce la funzione costruttore <code>Manager</code>, chiamando il costruttore <code>Empl</code><code>oyee</code> e specificando la proprietà <code>reports</code>. Infine, si assegna a un nuovo oggetto derivato da <code>Employee.prototype</code> come il prototipo per la funzione costruttore <code>Manager</code>. Quando si crea un nuovo <code>Manager</code>, questo eredita le proprietà <code>name</code> e <code>dept</code> dall'oggetto <code>Employee</code>.</p> + +<h3 id="Aggiungere_e_rimuovere_proprietà">Aggiungere e rimuovere proprietà</h3> + +<p>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à.</p> + +<h3 id="Riepilogo_delle_differenze">Riepilogo delle differenze</h3> + +<p>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.</p> + +<table class="standard-table"> + <caption>Confronto tra il sistema di oggetti basato su classi (Java) e il sistema di oggetti basato su prototipi (JavaScript)</caption> + <thead> + <tr> + <th scope="col">Class-based (Java)</th> + <th scope="col">Prototype-based (JavaScript)</th> + </tr> + </thead> + <tbody> + <tr> + <td>Classi e istanze sono entità separate.</td> + <td>Tutti gli oggetti possono ereditare da un altro oggetto.</td> + </tr> + <tr> + <td>Definire una classe con una definizione; istanziare una classe con un metodo costruttore</td> + <td>Definire e creare una collezione di oggetti con una funzione costruttore.</td> + </tr> + <tr> + <td>Creare un singolo oggetto con l'operatore <code>new</code>.</td> + <td>Uguale.</td> + </tr> + <tr> + <td>Costruire una gerarchia di oggetti usando la definizione di classe per definire le sottoclassi di classi esistenti.</td> + <td>Costruire una gerarchia di oggetti assegnando un oggetto come prototipo associato a una funzione costruttore.</td> + </tr> + <tr> + <td>Ereditare le proprietà seguendo la catena delle classi.</td> + <td>Ereditare le proprietà seguendo la catena dei prototipi.</td> + </tr> + <tr> + <td>La definizione di classe specifica <em>tutte</em> le proprietà di tutte le istanze della classe. Non è possibile aggiungere proprietà dinamicamente durante l'esecuzione.</td> + <td>La funzione costruttore o il prototipo specificano un set <em>iniziale</em> di proprietà. <span class="st">È possibile aggiungere o rimuovere dinamicamente proprietà ai singoli oggetti o all'intero gruppo di oggetti.</span></td> + </tr> + </tbody> +</table> + +<h2 id="L'esempio_'dipendente'">L'esempio 'dipendente'</h2> + +<p>Il resto di questo capitolo usa la gerarchia dei dipendenti mostrata nella figura seguente.</p> + +<div style="display: table-row;"> +<div style="display: table-cell; width: 350px; text-align: center; vertical-align: middle; padding: 10px;"> +<p>Una semplice gerarchia con gli oggetti seguenti:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/3060/figure8.1.png"></p> +</div> + +<div style="display: table-cell; vertical-align: middle; padding: 10px;"> +<ul> + <li><code>Employee</code> ha le proprietà <code>name</code> (il cui valore di default è una stringa vuota) e <code>dept</code> (il cui valore di default è "general").</li> + <li><code>Manager</code> è basato su <code>Employee</code>. Aggiunge la proprietà <code>reports</code> (il cui valore di default è un array vuoto, destinato a contenere una serie di oggetti <code>Employee</code>).</li> + <li><code>WorkerBee</code> è anch'esso basato su <code>Employee</code>. Aggiunge la proprietà <code>projects</code> (il cui valore di default è un array vuoto, destinato a contenere una serie di stringhe).</li> + <li><code>SalesPerson</code> è basato su <code>WorkerBee</code>. Aggiunge la proprietà <code>quota</code> (il cui valore di default è 100). Sovrascrive inoltre la proprietà <code>dept</code> con il valore "sales", che indica che tutti i venditori si trovano nello stesso dipartimento.</li> + <li><code>Engineer</code> è basato su <code>WorkerBee</code>. Aggiunge la proprietà <code>machine</code> (il cui valore di default è una stringa vuota) e sovrascrive la proprietà <code>dept</code> con il valore "engineering".</li> +</ul> +</div> +</div> + +<h2 id="Creazione_della_gerarchia">Creazione della gerarchia</h2> + +<p>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.</p> + +<p>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.</p> + +<p>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 <a href="#Costruttori_più_flessibili" rel="internal">Costruttori più flessibili</a>). Per adesso, queste semplici definizioni dimostrano come le proprietà vengono ereditate.</p> + +<p>Le seguenti definizioni Java e JavaScript di <code>Employee</code> 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<a href="https://it.wikipedia.org/wiki/Tipizzazione_forte"> linguaggio fortemente tipizzato</a> mentre JavaScript è un <a href="https://it.wikipedia.org/wiki/Tipizzazione_dinamica">linguaggio a tipizzazione dinamica</a>.</p> + +<div class="twocolumns"> +<h4 id="JavaScript">JavaScript</h4> + +<pre class="brush: js">function Employee() { + this.name = ""; + this.dept = "general"; +} +</pre> + +<h4 id="Java">Java</h4> + +<pre class="brush: java">public class Employee { + public String name = ""; + public String dept = "general"; +} +</pre> +</div> + +<p>Le definizioni di <code>Manager</code> e <code>WorkerBee</code> 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à <code>prototype</code> 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.</p> + +<div class="twocolumns"> +<h4 id="JavaScript_2">JavaScript</h4> + +<pre class="brush: js">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); +</pre> + +<h4 id="Java_2">Java</h4> + +<pre class="brush: java">public class Manager extends Employee { + public Employee[] reports = new Employee[0]; +} + + + +public class WorkerBee extends Employee { + public String[] projects = new String[0]; +} + + +</pre> +</div> + +<p>Le definizioni di <code>Engineer</code> e <code>SalesPerson</code> creano oggetti che discendono da <code>WorkerBee</code>, e quindi da <code>Employee</code>. 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à <code>dept</code> con nuovi valori specifici per questi oggetti.</p> + +<div class="twocolumns"> +<h4 id="JavaScript_3">JavaScript</h4> + +<pre class="brush: js">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); +</pre> + +<h4 id="Java_3">Java</h4> + +<pre class="brush: 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 = ""; +} + +</pre> +</div> + +<p>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.</p> + +<div class="note"> +<p><strong>Nota:</strong> Il termine <em>istanza</em> 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 <code><code>jane</code></code> è un'istanza di <code><code>Engineer</code></code>. Allo stesso modo, sebbene i termini <em>genitore </em>(<em>parent</em>), <em>figlio </em>(<em>child</em>), <em>antenato </em>(<em>ancestor</em>) e <em>discendente</em> (<em><em>descendant</em></em>) 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.</p> +</div> + +<h3 id="Creazione_di_oggetti_con_definizioni_semplici">Creazione di oggetti con definizioni semplici</h3> + +<div class="twocolumns"> +<h4 id="Gerarchia_degli_oggetti">Gerarchia degli oggetti</h4> + +<p>La gerarchia seguente è creata usando il codice sulla destra.</p> + +<p><img src="https://mdn.mozillademos.org/files/10412/=figure8.3.png"></p> + +<p> </p> + +<h4 id="singoli_oggetti">singoli oggetti</h4> + +<pre class="brush: js">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 '' +</pre> +</div> + +<h2 id="Proprietà_degli_oggetti">Proprietà degli oggetti</h2> + +<p>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.</p> + +<h3 id="Ereditare_le_proprietà">Ereditare le proprietà</h3> + +<p>Supponiamo di creare un nuovo oggetto <code>WorkerBee</code> chiamato <code>mark</code> con l'istruzione seguente:</p> + +<pre class="brush: js">var mark = new WorkerBee; +</pre> + +<p>Quando JavaScript vede l'operatore <code>new</code>, crea un nuovo oggeto generico e lo passa come valore della parola chiave <code>this</code> nella funzione costruttore <code>WorkerBee</code>. La funzione costruttore imposta esplicitamente il valore della proprietà <code>projects</code> e implicitamente il valore della proprietà interna <code>__proto__</code> uguale al valore <code>WorkerBee.prototype</code>. (Il nome di questa proprietà ha due underscores iniziali e due finali). La proprietà <code>__proto__</code> 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 <code>mark</code> per questo oggetto.</p> + +<p>Questo processo non inserisce esplicitamente valori nell'oggetto<code> mark</code> (valori <em>locali</em>) 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à <code>__proto__</code>). 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 <code>mark</code> ha le seguenti propietà con i rispettivi valori:</p> + +<pre class="brush: js">mark.name = ""; +mark.dept = "general"; +mark.projects = []; +</pre> + +<p>L'oggetto <code>mark</code> eredita i valori per le proprietà <code>name</code> e <code>dept</code> dall'oggetto prototipo presente in <code>mark.__proto__</code>. Il costruttore <code>WorkerBee</code> assegna un valore locale per la proprietà <code>projects</code>. L'ereditarietà di proprietà e valori in JavaScript fnziona in questo modo. Alcune sottigliezze su questo processo sono trattate nella sezione <a href="#Ereditare_le_proprietà_(revisited)">Ereditare le proprietà (revisited)</a>.</p> + +<p>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 <code>WorkerBee</code>. <span class="st">È</span> oviamente possibile cambiare i valori di ognuna di queste proprietà. <span class="st">È</span> quindi possibile assegnare informazioni specifice per <code>mark</code> nel modo seguente:</p> + +<pre class="brush: js">mark.name = "Doe, Mark"; +mark.dept = "admin"; +mark.projects = ["navigator"];</pre> + +<h3 id="Aggiungere_proprietà">Aggiungere proprietà</h3> + +<p>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::</p> + +<pre class="brush: js">mark.bonus = 3000; +</pre> + +<p>Ora, l'oggetto <code>mark</code>ha una proprietà <code>bonus</code>, ma nessun altro <code>WorkerBee</code> ha questa proprietà.</p> + +<p>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à <code>specialty</code> a tutti i dipendenti con l'istruzione seguente:</p> + +<pre class="brush: js">Employee.prototype.specialty = "none"; +</pre> + +<p>Non appena JavaScript esegue questa istruzione, anche l'oggetto <code>mark</code> avrà la proprietà <code>specialty</code> con il valore <code>"none"</code>. La figura seguente mostra cosa succede qunado questa proprietà viene aggiunta al prototipo <code>Employee</code> e in seguito la si sovrascrive per il prototipo <code>Engineer</code>.</p> + +<p><img alt="" class="internal" src="/@api/deki/files/4422/=figure8.4.png" style="height: 519px; width: 833px;"><br> + <small><strong>Aggiungere le proprietà</strong></small></p> + +<h2 id="Costruttori_più_flessibili">Costruttori più flessibili</h2> + +<p>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.</p> + +<p><img alt="" class="internal" id="figure8.5" src="/@api/deki/files/4423/=figure8.5.png" style="height: 481px; width: 1012px;"><br> + <small><strong>Specificare le proprietà in un costruttore, modo 1</strong></small></p> + +<p>La tabella seguente mostra le definizioni di questi oggetti in JavaScript e in Java.</p> + +<div class="twocolumns"> +<h4 id="JavaScript_4">JavaScript</h4> + +<h4 id="Java_4">Java</h4> +</div> + +<div class="twocolumns"> +<pre class="brush: js">function Employee (name, dept) { + this.name = name || ""; + this.dept = dept || "general"; +} +</pre> + +<p> </p> + +<p> </p> + +<p> </p> + +<p> </p> + +<pre class="brush: java">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; + } +} +</pre> +</div> + +<div class="twocolumns"> +<pre class="brush: js">function WorkerBee (projs) { + + this.projects = projs || []; +} +WorkerBee.prototype = new Employee; +</pre> + +<p> </p> + +<p> </p> + +<pre class="brush: java">public class WorkerBee extends Employee { + public String[] projects; + public WorkerBee () { + this(new String[0]); + } + public WorkerBee (String[] projs) { + projects = projs; + } +} +</pre> +</div> + +<div class="twocolumns"> +<pre class="brush: js"> +function Engineer (mach) { + this.dept = "engineering"; + this.machine = mach || ""; +} +Engineer.prototype = new WorkerBee; +</pre> + +<p> </p> + +<p> </p> + +<pre class="brush: java">public class Engineer extends WorkerBee { + public String machine; + public Engineer () { + dept = "engineering"; + machine = ""; + } + public Engineer (String mach) { + dept = "engineering"; + machine = mach; + } +} +</pre> +</div> + +<p>Queste definizioni JavaScript usano un linguaggio speciale per impostare i valori di default:</p> + +<pre class="brush: js">this.name = name || ""; +</pre> + +<p>In JavaScript l'operatore logico OR (<code>||</code>) valuta il suo primo argomento. Se questa espressione può essere convertita a <code>true</code>, l'operatore restituisce il primo argomento. Altrimenti l'operatore restituisce il valore del secondo argomento. Quindi, questa linea di codice verifica se <code>name</code> ha un valore utile per la proprietà <code>name</code>. Se ce l'ha, imposta <code>this.name</code> a questo valore. Altrimenti, imposta <code>this.name</code> a una stringa vuota. Questo capitolo usa questo linguaggio per brevità, comunque può disorientare a prima vista.</p> + +<div class="note"> +<p><strong>Nota:</strong> Potrebbe non funzionare come atteso se la funzione costruttore è chiamata con un argomento che converte a <code>false</code> (come ad esempio <code>0</code> (zero) o una stringa vuota (<code><code>""</code></code>)). In questo caso verrà scelto il valore di default.</p> +</div> + +<p>Con queste definizioni, quando si crea un'istanza di un oggetto, è possibile specificare i valori per le proprietà definite localmente. <span class="st">Per creare un nuovo <code>Engineer</code></span> è possibile utilizzare l'espressione seguente:</p> + +<pre class="brush: js">var jane = new Engineer("belau"); +</pre> + +<p>Le proprietà di <code>Jane</code> sono ora:</p> + +<pre class="brush: js">jane.name == ""; +jane.dept == "engineering"; +jane.projects == []; +jane.machine == "belau" +</pre> + +<p><span class="st">È</span> da notare che con queste definizioni non è possibile specificare una valore iniziale per le proprietà ereditate, come ad esempio <code>name</code>. Se si desidera specificare un valore iniziale per una proprietà ereditata, in JavaScript è necessario aggiungere ulteriore codice alla funzione costruttore.</p> + +<p>Finora, la funzione costruttore ha creato un oggetto generico e poi ha specificato proprietà locali e valori per il nuovo oggetto. <span class="st">È</span> 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.</p> + +<p><img alt="" class="internal" src="/@api/deki/files/4430/=figure8.6.png" style="height: 534px; width: 1063px;"><br> + <small><strong>Specificare le proprietà in un costruttore, modo 2</strong></small></p> + +<p>Guardiamo nel dettaglio una di queste definizioni. Ecco la nuova definizione per il costruttore <code>Engineer</code>:</p> + +<pre class="brush: js">function Engineer (name, projs, mach) { + this.base = WorkerBee; + this.base(name, "engineering", projs); + this.machine = mach || ""; +} +</pre> + +<p>Supponiamo di creare un nuovo oggetto <code>Engineer</code> nel modo seguente:</p> + +<pre class="brush: js">var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau"); +</pre> + +<p>JavaScript segue questa procedura:</p> + +<ol> + <li>L'operatore <code>new</code> crea un oggetto generico e imposta il valore <code>Engineer.prototype</code> per la sua proprietà <code>__proto__</code>.</li> + <li>L'operatore <code>new</code> passa il nuovo oggetto come valore della parola chiave <code>this</code> nella funzione costruttore <code>Engineer</code>.</li> + <li>Il costruttore crea una nuova proprietà per l'oggetto chiamata <code>base</code> e assegna il valore del costruttore <code>WorkerBee</code> alla proprietà <code>base</code>. Questo rende il costruttore <code>WorkerBee</code> un metode dell'oggetto <code>Engineer</code>. Il nome della proprietà <code>base</code> non è peculiare. <span class="st">È</span> possibile usare qualsiasi nome per la proprietà; <code>base</code> è semplicemente evocativo dello scopo.</li> + <li>Il costruttore chiama il metodo <code>base</code>, passando come suoi argomenti due degli argomenti passati al costruttore (<code>"Doe, Jane"</code> e <code>["navigator", "javascript"]</code>) e anche la stringa <code>"engineering"</code>. Usando esplicitamente <code>"engineering"</code> nel costruttore indica che tutti gli oggetti <code>Engineer</code> hanno lo stesso valore per la proprietà <code>dept</code> ereditata, e questo valore sovrascrive il valore ereditato dal costruttore <code>Employee</code>.</li> + <li>Poiché <code>base</code> è un metodo di <code>Engineer</code>, all'interno della chiamata di <code>base</code>, JavaScript aggiunge la parola chiave <code>this</code> all'oggetto creato al passaggio 1. In questo modo, la funzione <code>WorkerBee</code> a sua volta passa gli argomenti <code>"Doe, Jane"</code> e <code>"engineering"</code> alla funzione costruttore <code>Employee</code>. Dopo l'esecuzione della funzione costruttore <code>Employee</code>, la funzione <code>WorkerBee</code> utilizza l'argomento rimanente per impostare la proprietà<code> projects</code>.</li> + <li>Dopo l'esecuzione del metodo <code>base</code>, il costruttore <code>Engineer</code> inizializza la proprietà <code>machine</code> dell'oggetto al valore <code>"belau"</code>.</li> + <li>Dopo l'esecuzione del costruttore, JavaScript assegna il nuovo oggetto alla variabile <code>jane</code>.</li> +</ol> + +<p>Avendo chiamato il costruttore <code>WorkerBee</code> dall'interno del costruttore <code>Engineer</code>, si potrebbe pensare di aver impostato in modo corretto l'ereditarietà per gli oggetti <code>Engineer</code>. Questo non è il caso. Chiamare il costruttore <code>WorkerBee</code> assicura che un oggetto <code>Engineer</code> 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 <code>Employee</code> o <code>WorkerBee</code>, queste proprietà non saranno ereditate dall'oggetto <code>Engineer</code>. Per esempio, se si considera il codice seguente:</p> + +<pre class="brush: js">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"; +</pre> + +<p>L'oggetto <code>jane</code> non eredita la proprietà <code>specialty</code>. <span class="short_text" id="result_box" lang="it"><span>È</span></span> comunque necessario impostare esplicitamente il prototipo per garantire l'ereditarietà dinamica. Se si considera invece l'esempio seguente:</p> + +<pre class="brush: js">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"; +</pre> + +<p>Adesso il valore per l'oggetto <code>jane</code> della proprietà <code>specialty</code> è "none".</p> + +<p>Un altro modo per ereditare le proprietà è l'utilizzo dei metodi <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call" title="en-US/docs/JavaScript/Reference/Global Objects/Function/call">call()</a></code> e <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply" title="en-US/docs/JavaScript/Reference/Global Objects/Function/apply"><code>apply()</code></a>. Gli esempi sottostanti si equivalgono:</p> + +<div class="twocolumns"> +<pre class="brush: js">function Engineer (name, projs, mach) { + this.base = WorkerBee; + this.base(name, "engineering", projs); + this.machine = mach || ""; +} +</pre> + +<pre class="brush: js">function Engineer (name, projs, mach) { + WorkerBee.call(this, name, "engineering", projs); + this.machine = mach || ""; +} +</pre> +</div> + +<p>L'utilizzo del metodo <code>call()</code> costituisce un'implementazione più pulita poiché la proprietà <code>base</code> non è più necessaria.</p> + +<h2 id="Ereditare_le_proprietà_(revisited)">Ereditare le proprietà (revisited)</h2> + +<p>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.</p> + +<h3 id="Valori_locali_vs._valori_ereditati">Valori locali vs. valori ereditati</h3> + +<p>Quando si accede a una proprietà di un oggetto, JavaScript esegue i seguenti passaggi, come descritto in precedenza in questo capitolo:</p> + +<ol> + <li>Verifica se il valore è presente a livello locale. Se c'è, restituisce quel valore.</li> + <li>Se non è presente, verifica la catena dei prototipi (usando la proprietà <code>__proto__</code>).</li> + <li>Se un oggetto nella catena dei prototipi ha un valore per la proprietà specificata, restituisce quel valore.</li> + <li>Se la proprietà non viene trovata, l'oggetto non ha la proprietà.</li> +</ol> + +<p>Il risultato di questo processo dipende da come sono stati definiti gli elementi. L'esempio iniziale aveva queste definizioni:</p> + +<pre class="brush: js">function Employee () { + this.name = ""; + this.dept = "general"; +} + +function WorkerBee () { + this.projects = []; +} +WorkerBee.prototype = new Employee; +</pre> + +<p>Con queste definizioni, si supponga di creare <code>amy</code> come un'istanza di <code>WorkerBee</code> con la seguente istruzione:</p> + +<pre class="brush: js">var amy = new WorkerBee; +</pre> + +<p>L'oggetto <code>amy</code> ha una proprietà locale, <code>projects</code>. I valori per le proprietà <code>name</code> e <code>dept</code> non sono specifici per <code>amy</code> e quindi derivano dalla proprietà <code>__proto__</code> dell'oggetto <code>amy</code>. Quindi, <code>amy</code> ha i seguenti valori:</p> + +<pre class="brush: js">amy.name == ""; +amy.dept == "general"; +amy.projects == []; +</pre> + +<p>Ora si supponga di cambiare il valore della proprietà <code>name</code> nel prototipo associato con <code>Employee</code>:</p> + +<pre class="brush: js">Employee.prototype.name = "Unknown" +</pre> + +<p>Ci si potrebbe aspettare che il nuovo valore si propaghi a tutte le istanze di <code>Employee</code>. Invece, non lo fa.</p> + +<p>Quando si crea <em>qualsiasi </em>istanza dell'oggetto <code>Employee</code>, questa istanza riceve un <strong>valore locale</strong> per la proprietà <code>name</code> (la stringa vuota). Questo significa che quando si imposta il prototipo <code>WorkerBee</code> creando un nuovo oggetto <code>Employee</code>, <code>WorkerBee.prototype</code> avrà un valore locale per la proprietà <code>name</code>. Quindi, quando JavaScript legge la proprietà <code>name</code> dell'oggetto <code>amy</code> (istanza di <code>WorkerBee</code>), trova in <code>WorkerBee.prototype </code>il valore locale di questa proprietà. Pertanto non continua a cercare nella catena salendo a <code>Employee.prototype</code>.</p> + +<p>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:</p> + +<pre class="brush: js">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"; +</pre> + +<p>In questo caso, il valore della proprietà <code>name</code> di <code>amy</code> diventa "Unknown".</p> + +<p>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.</p> + +<h3 id="Determinazione_delle_relazioni_tra_istanze">Determinazione delle relazioni tra istanze</h3> + +<p>In JavaScript la ricerca delle proprietà (<em>property lookup</em>) controlla prima tra le proprietà specifiche dell'oggetto e, se il nome della proprietà non viene trovato, controlla la proprietà speciale <code>__proto__</code>. Il processo, chiamato "ricerca nella catena dei prototipi" (<em>lookup in the prototype chain</em>), continua ricorsivamente .</p> + +<p>Quando un oggetto viene costruito, la proprietà speciale <code>__proto__</code> viene impostata al valore della proprietà <code>prototype</code> del costruttore. L'espressione <code>new Foo()</code> crea un oggetto con <code>__proto__ == <code class="moz-txt-verticalline">Foo.prototype</code></code>. Di conseguenza, le modifiche alle proprietà di <code class="moz-txt-verticalline">Foo.prototype</code> alterano la ricerca delle proprietà per tutti gli oggetti che sono stati creati con <code>new Foo()</code>.</p> + +<p>Ogni oggetto ha una proprietà <code>__proto__</code> (ad eccezione di <code>Object</code>); ogni funzione ha una proprietà <code>prototype</code>. Quindi gli oggetti possono essere correlati ad altri oggetti attraverso una 'ereditarietà prototipale' (<em>prototypal inheritance</em>). <span class="st">È</span> possibile verificare l'ereditarietà confrontando la proprietà <code>__proto__</code> di un oggetto con l'oggetto <code>prototype</code> di una funzione. JavaScript fornisce una scorciatoia: l'operatore <code>instanceof</code> confronta un oggetto con una funzione e restituisce <code>true</code> se l'oggetto eredita dal prototipo della funzione. Per esempio,</p> + +<pre class="brush: js">var f = new Foo(); +var isTrue = (f instanceof Foo);</pre> + +<p>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 <a href="#Ereditare_le_proprietà">Ereditare le proprietà</a>. Creiamo un oggetto <code>Engineer</code> nel modo seguente:</p> + +<pre class="brush: js">var chris = new Engineer("Pigman, Chris", ["jsd"], "fiji"); +</pre> + +<p>Per questo oggetto, tutti gli enunciati seguenti sono veri:</p> + +<pre class="brush: js">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; +</pre> + +<p>Dato ciò, è possibile scrivere una funzione <code>instanceOf</code> come segue:</p> + +<pre class="brush: js">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; +} +</pre> + +<div class="note"> +<p><strong>Nota:</strong> 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) }}.</p> +</div> + +<p>Se si utilizza la funzione <code>instanceOf</code> definita in precedenza, queste espressioni sono vere:</p> + +<pre class="brush: js">instanceOf (chris, Engineer) +instanceOf (chris, WorkerBee) +instanceOf (chris, Employee) +instanceOf (chris, Object) +</pre> + +<p>Ma l'espressione seguente è falsa:</p> + +<pre class="brush: js">instanceOf (chris, SalesPerson) +</pre> + +<h3 id="Informazioni_globali_nei_costruttori">Informazioni globali nei costruttori</h3> + +<p>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 <code>Employee </code>si potrebbe usare la definizione seguente:</p> + +<pre class="brush: js">var idCounter = 1; + +function Employee (name, dept) { + this.name = name || ""; + this.dept = dept || "general"; + this.id = idCounter++; +} +</pre> + +<p>Con questa definizione, quando viene creato un nuovo <code>Employee</code>, il costruttore assegna l'ID seguente e incrementa il contatore globale (<code>idCounter</code>). Così, se l'istruzione successiva è la seguente, l'ID di <code>victoria </code>sarà 1, l'ID di <code>harry </code>sarà 2:</p> + +<pre class="brush: js">var victoria = new Employee("Pigbert, Victoria", "pubs") +var harry = new Employee("Tschopik, Harry", "sales") +</pre> + +<p>Questa a prima vista potrebbe sembrare la procedura corretta. Tuttavia, il contatore globale <code>idCounter</code> viene incrementato ogni volta che viene creato un oggetto <code>Employee</code>, per qualsiasi scopo. Se viene creata l'intera gerarchia di oggetti <code>Employee</code> mostrata in questo capitolo, il costruttore <code>Employee</code> viene chiamato ogni volta che si definisce un prototipo. Supponiamo di avere il codice seguente:</p> + +<pre class="brush: js">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"); +</pre> + +<p>Si assuma inoltre che le definizioni omesse abbiano la proprietà <code>base</code> 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 <code>mac</code>, il valore di <code>mac.id</code> sarà 5.</p> + +<p>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:</p> + +<pre class="brush: js">function Employee (name, dept) { + this.name = name || ""; + this.dept = dept || "general"; + if (name) + this.id = idCounter++; +} +</pre> + +<p>Quando viene creata un'istanza di <code>Employee</code> 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 <code>Employee</code> venga assegnato un ID, è necesario specificare un nome per il dipendente. In questo esempio, l'ID di <code>mac</code> sarà 1.</p> + +<h3 id="JavaScript_non_supporta_l'ereditarietà_multipla">JavaScript non supporta l'ereditarietà multipla</h3> + +<p>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.</p> + +<p>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.</p> + +<p>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:</p> + +<pre class="brush: js">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") +</pre> + +<p>Assumiamo inoltre che la definizione di <code>WorkerBee</code> sia quella usata in precedenza in questo capitolo. In questo caso, l'oggetto <code>dennis</code> avrà queste proprietà:</p> + +<pre class="brush: js">dennis.name == "Doe, Dennis" +dennis.dept == "engineering" +dennis.projects == ["collabra"] +dennis.machine == "hugo" +dennis.hobby == "scuba" +</pre> + +<p>Quindi <code>dennis</code> riceve la proprietà <code>hobby</code> dal costruttore <code>Hobbyist</code>. Però, se in seguito si aggiunge una proprietà al prototipo del costruttore <code>Hobbyist</code>:</p> + +<pre class="brush: js">Hobbyist.prototype.equipment = ["mask", "fins", "regulator", "bcd"] +</pre> + +<p>L'oggetto <code>dennis</code> non erediterà questa nuova proprietà.</p> + +<div>{{PreviousNext("Web/JavaScript/Guide/Working_with_Objects", "Web/JavaScript/Guide/Iterators_and_Generators")}}</div> diff --git a/files/it/web/javascript/guida/espressioni_regolari/index.html b/files/it/web/javascript/guida/espressioni_regolari/index.html new file mode 100644 index 0000000000..f876045948 --- /dev/null +++ b/files/it/web/javascript/guida/espressioni_regolari/index.html @@ -0,0 +1,647 @@ +--- +title: Espressioni regolari +slug: Web/JavaScript/Guida/Espressioni_Regolari +translation_of: Web/JavaScript/Guide/Regular_Expressions +--- +<div>{{jsSidebar("Guida JavaScript")}} {{PreviousNext("Web/JavaScript/Guide/Text_formatting", "Web/JavaScript/Guide/Indexed_collections")}}</div> + +<p class="summary">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.</p> + +<h2 id="Creazione_di_unespressione_regolare">Creazione di un'espressione regolare</h2> + +<p>Puoi creare un'espressione regolare in uno dei seguenti modi:</p> + +<ul> + <li> + <p>Usando un'espressione regolare letterale, che consiste in uno schema racchiuso tra slash, come segue:</p> + + <pre class="brush: js">var re = /ab+c/; +</pre> + + <p>Le Espressioni Regolari letterali forniscono la compilazione dell'espressione regolare quando lo script è caricato. Se l'espressione regolare rimane costante, usare questo modo può migliorare le prestazioni.</p> + </li> + <li> + <p>O chiamando il costruttore dell'oggetto {{jsxref("RegExp")}} object, come segue:</p> + + <pre class="brush: js">var re = new RegExp("ab+c"); +</pre> + + <p>Usando il costruttore avviene una compilazione runtime dell'espressione regolare. Usa il costruttore quando sai che lo schema dell'espressione regolare cambierà, o non sai lo schema a priori ma lo devi ricavare da un'altra risorsa, come un input dell'utente.</p> + </li> +</ul> + +<h2 id="Scrivere_uno_schema_per_espressioni_regolari">Scrivere uno schema per espressioni regolari</h2> + +<p>Uno schema di espressione regolare è composto da caratteri semplici, come <code>/abc/</code>, o da una combinazione di caratteri semplici e speciali, come <code>/ab*c/</code> o <code>/Chapter (\d+)\.\d*/</code>. 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") }}.</p> + +<div class="blockIndicator note"> +<p><strong>Nota:</strong> Se hai già familiarità con la struttura di un'espressione regolare, potresti anche leggere <a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Cheatsheet">il cheatsheet</a> per una rapida ricerca di un modello/costrutto specifico</p> +</div> + +<h3 id="Usare_modelli_semplici">Usare modelli semplici</h3> + +<p><span class="tlid-translation translation" lang="it"><span title="">I modelli semplici sono costituiti da carattrei per i quali si desidera trovare una corrispondenza diretta.</span> <span title="">Ad esempio, il modello</span></span> <code>/abc/</code> <span class="tlid-translation translation" lang="it"><span title=""> corrisponde solo quando esattamente i caratteri </span></span> <code>"abc"</code> <span class="tlid-translation translation" lang="it"><span title=""> si presentano insieme e in quell'ordine.</span> <span title="">Una tale corrispondenza avrebbe successo nelle stringhe </span></span> <code>"Ciao, conosci il tuo abc?"</code> e <span class="tlid-translation translation" lang="it"> <span title=""><code>"Gli ultimi progetti di aeroplani si sono evoluti da slabcraft"</code>.</span> <span title="">In entrambi i casi la corrispondenza con la sottostringa <code>"abc"</code> avviene.</span> <span title="">Non c'è corrispondenza nella stringa <code>"Grab crab"</code> perché invece di contenere l'esatta sottostringa <code>"abc"</code> coniente la sottostringa <code>"ab c".</code></span></span></p> + +<h3 id="Usare_caratteri_speciali">Usare caratteri speciali</h3> + +<p><span class="tlid-translation translation" lang="it"><span title="">Quando la ricerca di una corrispondenza richiede qualcosa di più di una corrispondenza diretta, come la ricerca di una o più <em>b</em> o la ricerca di spazi bianchi, il modello include caratteri speciali.</span></span> Ad esempio, per abbinare una singola <code>"a" </code>seguita da zero o più <code>"b"</code> seguita da <code>"c"</code>, dovresti usare il modello <code>/ab*c/</code>: il <code>*</code> dopo <code>"b"</code> significa "0 o più occorrenze dell'elemento precedente". Nella stringa <code>"cbbabbbbcdebc"</code>, questo modello corrisponderà alla sottostringa <code>"abbbbc"</code>.<br> + <br> + <span class="tlid-translation translation" lang="it"><span title="">La tabella seguente fornisce un elenco completo e una descrizione dei caratteri speciali che possono essere utilizzati nelle espressioni regolari.</span></span></p> + +<table class="standard-table"> + <caption>Caratteri speciali nelle espressioni regolari</caption> + <thead> + <tr> + <th scope="col">Carattere</th> + <th scope="col">Significato/Utilizzo</th> + </tr> + </thead> + <tbody> + <tr> + <td><a href="#special-backslash" id="special-backslash" name="special-backslash"><code>\</code></a></td> + <td> + <p>Matches according to the following rules:<br> + <br> + 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 '<code>b</code>' without a preceding '\' generally matches lowercase 'b's wherever they occur. But a '<code>\b</code>' by itself doesn't match any character; it forms the special <a href="#special-word-boundary" title="#special-word-boundary">word boundary character</a>.<br> + <br> + A backslash that precedes a special character indicates that the next character is not special and should be interpreted literally. For example, the pattern <code>/a*/</code> relies on the special character '<code>*</code>' to match 0 or more a's. By contrast, the pattern <code>/a\*/</code> removes the specialness of the '<code>*</code>' to enable matches with strings like 'a*'.<br> + <br> + Do not forget to escape \ itself while using the RegExp("pattern") notation because \ is also an escape character in strings.</p> + </td> + </tr> + <tr> + <td><a href="#special-caret" id="special-caret" name="special-caret"><code>^</code></a></td> + <td>Matches beginning of input. If the multiline flag is set to true, also matches immediately after a line break character.<br> + <br> + For example, <code>/^A/</code> does not match the 'A' in "an A", but does match the 'A' in "An E".<br> + <br> + The '<code>^</code>' has a different meaning when it appears as the first character in a character set pattern. See <a href="#special-negated-character-set" title="#special-negated-character-set">complemented character sets</a> for details and an example.</td> + </tr> + <tr> + <td><a href="#special-dollar" id="special-dollar" name="special-dollar"><code>$</code></a></td> + <td> + <p>Matches end of input. If the multiline flag is set to true, also matches immediately before a line break character.</p> + + <p>For example, <code>/t$/</code> does not match the 't' in "eater", but does match it in "eat".</p> + </td> + </tr> + <tr> + <td><a href="#special-asterisk" id="special-asterisk" name="special-asterisk"><code>*</code></a></td> + <td> + <p>Matches the preceding expression 0 or more times. Equivalent to {0,}.</p> + + <p>For example, <code>/bo*/</code> matches 'boooo' in "A ghost booooed" and 'b' in "A bird warbled", but nothing in "A goat grunted".</p> + </td> + </tr> + <tr> + <td><a href="#special-plus" id="special-plus" name="special-plus"><code>+</code></a></td> + <td> + <p>Matches the preceding expression 1 or more times. Equivalent to <code>{1,}</code>.</p> + + <p>For example, <code>/a+/</code> matches the 'a' in "candy" and all the a's in "caaaaaaandy", but nothing in "cndy".</p> + </td> + </tr> + <tr> + <td><a href="#special-questionmark" id="special-questionmark" name="special-questionmark"><code>?</code></a></td> + <td>Matches the preceding expression 0 or 1 time. Equivalent to <code>{0,1}</code>.<br> + <br> + For example, <code>/e?le?/</code> matches the 'el' in "angel" and the 'le' in "angle" and also the 'l' in "oslo".<br> + <br> + 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 <code>/\d+/</code> to "123abc" matches "123". But applying <code>/\d+?/</code> to that same string matches only the "1".<br> + <br> + Also used in lookahead assertions, as described in the <code>x(?=y)</code> and <code>x(?!y)</code> entries of this table.<br> + </td> + </tr> + <tr> + <td><a href="#special-dot" id="special-dot" name="special-dot"><code>.</code></a></td> + <td> + <p>(The decimal point) matches any single character except the newline character.</p> + + <p>For example, <code>/.n/</code> matches 'an' and 'on' in "nay, an apple is on the tree", but not 'nay'.</p> + </td> + </tr> + <tr> + <td><a href="#special-capturing-parentheses" id="special-capturing-parentheses" name="special-capturing-parentheses"><code>(x)</code></a></td> + <td> + <p>Matches 'x' and remembers the match, as the following example shows. The parentheses are called <em>capturing parentheses</em>.<br> + <br> + The '<code>(foo)</code>' and '<code>(bar)</code>' in the pattern <code>/(foo) (bar) \1 \2/</code> match and remember the first two words in the string "foo bar foo bar". The <code>\1 </code>and <code>\2</code> in the pattern match the string's last two words. Note that <code>\1, \2, \n</code> are used in the matching part of the regex. In the replacement part of a regex the syntax <code>$1, $2, $n</code> must be used, e.g.: <code>'bar foo'.replace( /(...) (...)/, '$2 $1' )</code>.</p> + </td> + </tr> + <tr> + <td><a href="#special-non-capturing-parentheses" id="special-non-capturing-parentheses" name="special-non-capturing-parentheses"><code>(?:x)</code></a></td> + <td>Matches 'x' but does not remember the match. The parentheses are called <em>non-capturing parentheses</em>, and let you define subexpressions for regular expression operators to work with. Consider the sample expression <code>/(?:foo){1,2}/</code>. If the expression was <code>/foo{1,2}/</code>, the <code>{1,2}</code> characters would apply only to the last 'o' in 'foo'. With the non-capturing parentheses, the <code>{1,2}</code> applies to the entire word 'foo'.</td> + </tr> + <tr> + <td><a href="#special-lookahead" id="special-lookahead" name="special-lookahead"><code>x(?=y)</code></a></td> + <td> + <p>Matches 'x' only if 'x' is followed by 'y'. This is called a lookahead.</p> + + <p>For example, <code>/Jack(?=Sprat)/</code> matches 'Jack' only if it is followed by 'Sprat'. <code>/Jack(?=Sprat|Frost)/</code> matches 'Jack' only if it is followed by 'Sprat' or 'Frost'. However, neither 'Sprat' nor 'Frost' is part of the match results.</p> + </td> + </tr> + <tr> + <td><a href="#special-negated-look-ahead" id="special-negated-look-ahead" name="special-negated-look-ahead"><code>x(?!y)</code></a></td> + <td> + <p>Matches 'x' only if 'x' is not followed by 'y'. This is called a negated lookahead.</p> + + <p>For example, <code>/\d+(?!\.)/</code> matches a number only if it is not followed by a decimal point. The regular expression <code>/\d+(?!\.)/.exec("3.141")</code> matches '141' but not '3.141'.</p> + </td> + </tr> + <tr> + <td><a href="#special-or" id="special-or" name="special-or"><code>x|y</code></a></td> + <td> + <p>Matches either 'x' or 'y'.</p> + + <p>For example, <code>/green|red/</code> matches 'green' in "green apple" and 'red' in "red apple."</p> + </td> + </tr> + <tr> + <td><a href="#special-quantifier" id="special-quantifier" name="special-quantifier"><code>{n}</code></a></td> + <td>Matches exactly n occurrences of the preceding expression. N must be a positive integer.<br> + <br> + For example, <code>/a{2}/</code> 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."</td> + </tr> + <tr> + <td><a href="#special-quantifier-range" id="special-quantifier-range" name="special-quantifier-range"><code>{n,m}</code></a></td> + <td> + <p>Where <code>n</code> and <code>m</code> are positive integers and <code>n <= m</code>. Matches at least <code>n</code> and at most <code>m</code> occurrences of the preceding expression. When <code>m</code> is omitted, it's treated as ∞.</p> + + <p>For example, <code>/a{1,3}/</code> 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.</p> + </td> + </tr> + <tr> + <td><a href="#special-character-set" id="special-character-set" name="special-character-set"><code>[xyz]</code></a></td> + <td>Character set. This pattern type matches any one of the characters in the brackets, including <a href="https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Values,_variables,_and_literals#Unicode_escape_sequences" title="https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Values,_variables,_and_literals#Unicode_escape_sequences">escape sequences</a>. Special characters like the dot(<code>.</code>) and asterisk (<code>*</code>) 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.<br> + <br> + The pattern<code> [a-d]</code>, which performs the same match as <code>[abcd]</code>, matches the 'b' in "brisket" and the 'c' in "city". The patterns <code>/[a-z.]+/ </code>and <code>/[\w.]+/</code> match the entire string "test.i.ng".</td> + </tr> + <tr> + <td><a href="#special-negated-character-set" id="special-negated-character-set" name="special-negated-character-set"><code>[^xyz]</code></a></td> + <td> + <p>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.</p> + + <p>For example, <code>[^abc]</code> is the same as <code>[^a-c]</code>. They initially match 'r' in "brisket" and 'h' in "chop."</p> + </td> + </tr> + <tr> + <td><a href="#special-backspace" id="special-backspace" name="special-backspace"><code>[\b]</code></a></td> + <td>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 <code>\b</code>.)</td> + </tr> + <tr> + <td><a href="#special-word-boundary" id="special-word-boundary" name="special-word-boundary"><code>\b</code></a></td> + <td> + <p>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 <code>[\b]</code>.)</p> + + <p>Examples:<br> + <code>/\bm/</code> matches the 'm' in "moon" ;<br> + <code>/oo\b/</code> does not match the 'oo' in "moon", because 'oo' is followed by 'n' which is a word character;<br> + <code>/oon\b/</code> matches the 'oon' in "moon", because 'oon' is the end of the string, thus not followed by a word character;<br> + <code>/\w\b\w/</code> will never match anything, because a word character can never be followed by both a non-word and a word character.</p> + + <div class="note"> + <p><strong>Note:</strong> JavaScript's regular expression engine defines a <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-15.10.2.6">specific set of characters</a> 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.</p> + </div> + </td> + </tr> + <tr> + <td><a href="#special-non-word-boundary" id="special-non-word-boundary" name="special-non-word-boundary"><code>\B</code></a></td> + <td> + <p>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.</p> + + <p>For example, <code>/\B../</code> matches 'oo' in "noonday", and <code>/y\B./</code> matches 'ye' in "possibly yesterday."</p> + </td> + </tr> + <tr> + <td><a href="#special-control" id="special-control" name="special-control"><code>\c<em>X</em></code></a></td> + <td> + <p>Where <em>X</em> is a character ranging from A to Z. Matches a control character in a string.</p> + + <p>For example, <code>/\cM/</code> matches control-M (U+000D) in a string.</p> + </td> + </tr> + <tr> + <td><a href="#special-digit" id="special-digit" name="special-digit"><code>\d</code></a></td> + <td> + <p>Matches a digit character. Equivalent to <code>[0-9]</code>.</p> + + <p>For example, <code>/\d/</code> or <code>/[0-9]/</code> matches '2' in "B2 is the suite number."</p> + </td> + </tr> + <tr> + <td><a href="#special-non-digit" id="special-non-digit" name="special-non-digit"><code>\D</code></a></td> + <td> + <p>Matches any non-digit character. Equivalent to <code>[^0-9]</code>.</p> + + <p>For example, <code>/\D/</code> or <code>/[^0-9]/</code> matches 'B' in "B2 is the suite number."</p> + </td> + </tr> + <tr> + <td><a href="#special-form-feed" id="special-form-feed" name="special-form-feed"><code>\f</code></a></td> + <td>Matches a form feed (U+000C).</td> + </tr> + <tr> + <td><a href="#special-line-feed" id="special-line-feed" name="special-line-feed"><code>\n</code></a></td> + <td>Matches a line feed (U+000A).</td> + </tr> + <tr> + <td><a href="#special-carriage-return" id="special-carriage-return" name="special-carriage-return"><code>\r</code></a></td> + <td>Matches a carriage return (U+000D).</td> + </tr> + <tr> + <td><a href="#special-white-space" id="special-white-space" name="special-white-space"><code>\s</code></a></td> + <td> + <p>Matches a single white space character, including space, tab, form feed, line feed. Equivalent to <code>[ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]</code>.</p> + + <p>For example, <code>/\s\w*/</code> matches ' bar' in "foo bar."</p> + </td> + </tr> + <tr> + <td><a href="#special-non-white-space" id="special-non-white-space" name="special-non-white-space"><code>\S</code></a></td> + <td> + <p>Matches a single character other than white space. Equivalent to <code>[^ \f\n\r\t\v\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]</code>.</p> + + <p>For example, <code>/\S\w*/</code> matches 'foo' in "foo bar."</p> + </td> + </tr> + <tr> + <td><a href="#special-tab" id="special-tab" name="special-tab"><code>\t</code></a></td> + <td>Matches a tab (U+0009).</td> + </tr> + <tr> + <td><a href="#special-vertical-tab" id="special-vertical-tab" name="special-vertical-tab"><code>\v</code></a></td> + <td>Matches a vertical tab (U+000B).</td> + </tr> + <tr> + <td><a href="#special-word" id="special-word" name="special-word"><code>\w</code></a></td> + <td> + <p>Matches any alphanumeric character including the underscore. Equivalent to <code>[A-Za-z0-9_]</code>.</p> + + <p>For example, <code>/\w/</code> matches 'a' in "apple," '5' in "$5.28," and '3' in "3D."</p> + </td> + </tr> + <tr> + <td><a href="#special-non-word" id="special-non-word" name="special-non-word"><code>\W</code></a></td> + <td> + <p>Matches any non-word character. Equivalent to <code>[^A-Za-z0-9_]</code>.</p> + + <p>For example, <code>/\W/</code> or <code>/[^A-Za-z0-9_]/</code> matches '%' in "50%."</p> + </td> + </tr> + <tr> + <td><a href="#special-backreference" id="special-backreference" name="special-backreference"><code>\<em>n</em></code></a></td> + <td> + <p>Where <em>n</em> is a positive integer, a back reference to the last substring matching the <em>n</em> parenthetical in the regular expression (counting left parentheses).</p> + + <p>For example, <code>/apple(,)\sorange\1/</code> matches 'apple, orange,' in "apple, orange, cherry, peach."</p> + </td> + </tr> + <tr> + <td><a href="#special-null" id="special-null" name="special-null"><code>\0</code></a></td> + <td>Matches a NULL (U+0000) character. Do not follow this with another digit, because <code>\0<digits></code> is an octal <a href="https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Values,_variables,_and_literals#Unicode_escape_sequences" title="https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Values,_variables,_and_literals#Unicode_escape_sequences">escape sequence</a>.</td> + </tr> + <tr> + <td><a href="#special-hex-escape" id="special-hex-escape" name="special-hex-escape"><code>\xhh</code></a></td> + <td>Matches the character with the code hh (two hexadecimal digits)</td> + </tr> + <tr> + <td><a href="#special-unicode-escape" id="special-unicode-escape" name="special-unicode-escape"><code>\uhhhh</code></a></td> + <td>Matches the character with the code hhhh (four hexadecimal digits).</td> + </tr> + <tr> + <td><a href="#special-unicode-escape-es6" id="special-unicode-escape-es6" name="special-unicode-escape-es6"><code>\u{hhhh}</code></a></td> + <td>(only when u flag is set) Matches the character with the Unicode value hhhh (hexadecimal digits).</td> + </tr> + </tbody> +</table> + +<p>Escaping user input to be treated as a literal string within a regular expression can be accomplished by simple replacement:</p> + +<pre class="brush: js">function escapeRegExp(string){ + return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string +}</pre> + +<h3 id="Using_parentheses">Using parentheses</h3> + +<p>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") }}.</p> + +<p>For example, the pattern <code>/Chapter (\d+)\.\d*/</code> 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 (<code>\d</code> means any numeric character and <code>+</code> 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 (<code>\d</code> means numeric character, <code>*</code> means 0 or more times). In addition, parentheses are used to remember the first matched numeric characters.</p> + +<p>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'.</p> + +<p>To match a substring without causing the matched part to be remembered, within the parentheses preface the pattern with <code>?:</code>. For example, <code>(?:\d+)</code> matches one or more numeric characters but does not remember the matched characters.</p> + +<h2 id="Lavorare_con_le_espressioni_regolari">Lavorare con le espressioni regolari</h2> + +<p>Le espressioni regolari sono usate con i metodi <code>test</code> and <code>exec</code> di <code>RegExp</code> e con i metodi <code>match</code>, <code>replace</code>, <code>search</code>, and <code>split</code> di <code>String</code> .Questi metodi sono spiegati in dettaglio nelle <a href="/en-US/docs/Web/JavaScript/Reference" title="en-US/docs/JavaScript/Reference">JavaScript reference</a>.</p> + +<p>Metodi che usano le espressioni regolari</p> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Metodo</th> + <th scope="col">Descrizione</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{jsxref("RegExp.exec", "exec")}}</td> + <td> + <p>Un metodo di <code>RegExp</code> che esegue una ricerca per una corrispondenza in una stringa. Ritorna un array di informazioni, o null se non trova corrispondenze.</p> + </td> + </tr> + <tr> + <td>{{jsxref("RegExp.test", "test")}}</td> + <td>Un metodo di <code>RegExp</code> che testa le corrispondenze in una stinga. Ritorna true o false. </td> + </tr> + <tr> + <td>{{jsxref("String.match", "match")}}</td> + <td>Un metodo di <code>String</code> che esegue una ricerca per una corrispondenza in una stringa. Ritorna un array di informazioni, o null se non trova corrispondenze.</td> + </tr> + <tr> + <td>{{jsxref("String.search", "search")}}</td> + <td>A <code>String</code> method that tests for a match in a string. It returns the index of the match, or -1 if the search fails.</td> + </tr> + <tr> + <td>{{jsxref("String.replace", "replace")}}</td> + <td>A <code>String</code> method that executes a search for a match in a string, and replaces the matched substring with a replacement substring.</td> + </tr> + <tr> + <td>{{jsxref("String.split", "split")}}</td> + <td>A <code>String</code> method that uses a regular expression or a fixed string to break a string into an array of substrings.</td> + </tr> + </tbody> +</table> + +<p>When you want to know whether a pattern is found in a string, use the <code>test</code> or <code>search</code> method; for more information (but slower execution) use the <code>exec</code> or <code>match</code> methods. If you use <code>exec</code> or <code>match</code> 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, <code>RegExp</code>. If the match fails, the <code>exec</code> method returns <code>null</code> (which coerces to <code>false</code>).</p> + +<p>In the following example, the script uses the <code>exec</code> method to find a match in a string.</p> + +<pre class="brush: js">var myRe = /d(b+)d/g; +var myArray = myRe.exec("cdbbdbsbz"); +</pre> + +<p>If you do not need to access the properties of the regular expression, an alternative way of creating <code>myArray</code> is with this script:</p> + +<pre class="brush: js">var myArray = /d(b+)d/g.exec("cdbbdbsbz"); // equivalent to "cdbbdbsbz".match(/d(b+)d/g); +</pre> + +<p>If you want to construct the regular expression from a string, yet another alternative is this script:</p> + +<pre class="brush: js">var myRe = new RegExp("d(b+)d", "g"); +var myArray = myRe.exec("cdbbdbsbz"); +</pre> + +<p>With these scripts, the match succeeds and returns the array and updates the properties shown in the following table.</p> + +<table class="standard-table"> + <caption>Results of regular expression execution.</caption> + <thead> + <tr> + <th scope="col">Object</th> + <th scope="col">Property or index</th> + <th scope="col">Description</th> + <th scope="col">In this example</th> + </tr> + </thead> + <tbody> + <tr> + <td rowspan="4"><code>myArray</code></td> + <td></td> + <td>The matched string and all remembered substrings.</td> + <td><code>["dbbd", "bb"]</code></td> + </tr> + <tr> + <td><code>index</code></td> + <td>The 0-based index of the match in the input string.</td> + <td><code>1</code></td> + </tr> + <tr> + <td><code>input</code></td> + <td>The original string.</td> + <td><code>"cdbbdbsbz"</code></td> + </tr> + <tr> + <td><code>[0]</code></td> + <td>The last matched characters.</td> + <td><code>"dbbd"</code></td> + </tr> + <tr> + <td rowspan="2"><code>myRe</code></td> + <td><code>lastIndex</code></td> + <td>The 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") }}.)</td> + <td><code>5</code></td> + </tr> + <tr> + <td><code>source</code></td> + <td>The text of the pattern. Updated at the time that the regular expression is created, not executed.</td> + <td><code>"d(b+)d"</code></td> + </tr> + </tbody> +</table> + +<p>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:</p> + +<pre class="brush: js">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" +</pre> + +<p>However, if you have this script:</p> + +<pre class="brush: js">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" +</pre> + +<p>The occurrences of <code>/d(b+)d/g</code> in the two statements are different regular expression objects and hence have different values for their <code>lastIndex</code> 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.</p> + +<h3 id="Using_parenthesized_substring_matches">Using parenthesized substring matches</h3> + +<p>Including parentheses in a regular expression pattern causes the corresponding submatch to be remembered. For example, <code>/a(b)c/</code> matches the characters 'abc' and remembers 'b'. To recall these parenthesized substring matches, use the <code>Array</code> elements <code>[1]</code>, ..., <code>[n]</code>.</p> + +<p>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.</p> + +<p>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 <code>$1</code> and <code>$2</code> in the replacement to denote the first and second parenthesized substring matches.</p> + +<pre class="brush: js">var re = /(\w+)\s(\w+)/; +var str = "John Smith"; +var newstr = str.replace(re, "$2, $1"); +console.log(newstr); +</pre> + +<p>This prints "Smith, John".</p> + +<h3 id="Advanced_searching_with_flags">Advanced searching with flags</h3> + +<p>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.</p> + +<table class="standard-table"> + <caption>Regular expression flags</caption> + <thead> + <tr> + <th scope="col">Flag</th> + <th scope="col">Description</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>g</code></td> + <td>Global search.</td> + </tr> + <tr> + <td>i</td> + <td>Case-insensitive search.</td> + </tr> + <tr> + <td>m</td> + <td>Multi-line search.</td> + </tr> + <tr> + <td>y</td> + <td>Perform a "sticky" search that matches starting at the current position in the target string. See {{jsxref("RegExp.sticky", "sticky")}}</td> + </tr> + </tbody> +</table> + +<p>To include a flag with the regular expression, use this syntax:</p> + +<pre class="brush: js">var re = /pattern/flags; +</pre> + +<p>or</p> + +<pre class="brush: js">var re = new RegExp("pattern", "flags"); +</pre> + +<p>Note that the flags are an integral part of a regular expression. They cannot be added or removed later.</p> + +<p>For example, <code>re = /\w+\s/g</code> creates a regular expression that looks for one or more characters followed by a space, and it looks for this combination throughout the string.</p> + +<pre class="brush: js">var re = /\w+\s/g; +var str = "fee fi fo fum"; +var myArray = str.match(re); +console.log(myArray); +</pre> + +<p>This displays ["fee ", "fi ", "fo "]. In this example, you could replace the line:</p> + +<pre class="brush: js">var re = /\w+\s/g; +</pre> + +<p>with:</p> + +<pre class="brush: js">var re = new RegExp("\\w+\\s", "g"); +</pre> + +<p>and get the same result.</p> + +<p>The <code>m</code> flag is used to specify that a multiline input string should be treated as multiple lines. If the <code>m</code> flag is used, <code>^</code> and <code>$</code> match at the start or end of any line within the input string instead of the start or end of the entire string.</p> + +<h2 id="Examples">Examples</h2> + +<p>The following examples show some uses of regular expressions.</p> + +<h3 id="Changing_the_order_in_an_input_string">Changing the order in an input string</h3> + +<p>The following example illustrates the formation of regular expressions and the use of <code>string.split()</code> and <code>string.replace()</code>. 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.</p> + +<pre class="brush: js">// 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")); +</pre> + +<h3 id="Using_special_characters_to_verify_input">Using special characters to verify input</h3> + +<p>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.</p> + +<p>Within non-capturing parentheses <code>(?:</code> , the regular expression looks for three numeric characters <code>\d{3}</code> OR <code>|</code> a left parenthesis <code>\(</code> followed by three digits<code> \d{3}</code>, followed by a close parenthesis <code>\)</code>, (end non-capturing parenthesis <code>)</code>), followed by one dash, forward slash, or decimal point and when found, remember the character <code>([-\/\.])</code>, followed by three digits <code>\d{3}</code>, followed by the remembered match of a dash, forward slash, or decimal point <code>\1</code>, followed by four digits <code>\d{4}</code>.</p> + +<p>The <code>Change</code> event activated when the user presses Enter sets the value of <code>RegExp.input</code>.</p> + +<pre class="brush: html"><!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> +</pre> + +<div>{{PreviousNext("Web/JavaScript/Guide/Text_formatting", "Web/JavaScript/Guide/Indexed_collections")}}</div> diff --git a/files/it/web/javascript/guida/functions/index.html b/files/it/web/javascript/guida/functions/index.html new file mode 100644 index 0000000000..4aca8d5a7b --- /dev/null +++ b/files/it/web/javascript/guida/functions/index.html @@ -0,0 +1,646 @@ +--- +title: Funzioni +slug: Web/JavaScript/Guida/Functions +translation_of: Web/JavaScript/Guide/Functions +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Loops_and_iteration", "Web/JavaScript/Guide/Expressions_and_Operators")}}</div> + +<div> </div> + +<p><strong>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 <em>scope</em> dal quale la si invocherà.</strong></p> + +<p>Vedi anche <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions">l'esaustivo capitolo della guida di riferimento, che tratta delle funzioni </a><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions">JavaScript</a>, per avere maggiori dettagli.</p> + +<h2 id="Definire_una_funzione">Definire una funzione</h2> + +<h3 id="Dichiarazioni_di_funzione">Dichiarazioni di funzione</h3> + +<p>Una <strong>definizione di funzione</strong> ( o <strong>dichiarazione di funzione</strong>, o <strong>istruzione di funzione </strong>) consiste della parola chiave <a href="/en-US/docs/Web/JavaScript/Reference/Statements/function" title="function"><code>function</code></a>, seguita da:</p> + +<ul> + <li>il nome della funzione.</li> + <li>una lista di argomenti per la funzione, chiusi tra due parentesi e separati da una virgola.</li> + <li>le istruzioni JavaScript che definiscono la funzione, chiuse tra due parentesi graffe, <code>{ }</code>.</li> +</ul> + +<p>Per esempio, il codice seguente definisce una funzione semplice chiamata <em>square</em>:</p> + +<pre class="brush: js">function square(number) { + return number * number; +} +</pre> + +<p>La funzione <em><code>square</code></em> riceve un argomento, chiamato <em><code>number</code></em>. La funzione contiene una sola istruzione che dice di restituire ( <em>return</em> ) l'argomento della funzione ( <em><code>number </code></em>) moltiplicato per se stesso. L'istruzione <a href="/en-US/docs/Web/JavaScript/Reference/Statements/return" title="return"><code>return</code></a> specifica il valore restituito dalla funzione.</p> + +<pre class="brush: js">return number * number; +</pre> + +<p>I parametri primitivi ( quale un numero ) vengono passati alla funzione come <strong>valore</strong>; 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 ).</p> + +<p>Se, invece, alla funzione viene passato un oggetto ( un valore non-primitivo, come, ad esempio, un <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array" title="The JavaScript Array object is a global object that is used in the construction of arrays; which are high-level, list-like objects."><code>Array</code></a> 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:</p> + +<pre class="brush: js">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) +</pre> + +<h3 id="Espressioni_di_funzione">Espressioni di funzione</h3> + +<p>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 <strong>anonima</strong>; vale a dire, non deve avere un nome. Per esempio, la funzione <em><code>square</code></em> potrebbe essere stata definita come:</p> + +<pre class="brush: js">var square = function(number) { return number * number }; +var x = square(4) // x gets the value 16</pre> + +<p>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:</p> + +<pre class="brush: js">var factorial = function fac(n) { return n<2 ? 1 : n*fac(n-1) }; + +console.log(factorial(3)); +</pre> + +<p>NB: l'oggetto <em>console</em> non è un oggetto standard. Non usatelo in un sito web, poichè potrebbe non funzionare correttamente. Per verificare il funzionamento dell'esempio precedente, usate, piuttosto:</p> + +<p> window.alert(factorial(3));</p> + +<p>Le espressioni di funzione sono utili quando si vuole passare una funzione ad un'altra funzione, come argomento. Il prossimo esempio mostra una funzione <code>map</code> che viene definita e poi invocata, con una funzione anonima come primo parametro:</p> + +<pre class="brush: js">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; +} +</pre> + +<p>Il seguente codice:</p> + +<pre class="brush: js">map(function(x) {return x * x * x}, [0, 1, 2, 5, 10]); +</pre> + +<p>restituisce [0, 1, 8, 125, 1000].</p> + +<p>In JavaScript, una funzione può essere definita in base ad una condizione. Per esempio, la definizione di funzione seguente definisce la funzione <code>myFunc</code> solo se <code>num</code> è uguale a 0 ( zero ):</p> + +<pre class="brush: js">var myFunc; +if (num == 0){ + myFunc = function(theObject) { + theObject.make = "Toyota" + } +}</pre> + +<p>Per definire una funzione, inoltre, è possibile usare il costruttore <a class="new" href="https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Function" title="The documentation about this has not yet been written; please consider contributing!"><code>Function</code></a>, per creare funzioni da una stringa, in runtime, in modo simile a <a class="new" title="The documentation about this has not yet been written; please consider contributing!"><code>eval()</code></a>.</p> + +<p>Un <strong>metodo</strong> è una funzione che è una proprietà di un oggetto. Leggi di più sugli oggetti e sui metodi in <a href="/en-US/docs/Web/JavaScript/Guide/Working_with_Objects" title="en-US/docs/JavaScript/Guide/Working with Objects">Working with objects</a>.</p> + +<h2 id="Chiamare_(_invocare_)_una_funzione">Chiamare ( invocare ) una funzione</h2> + +<p>Definire una funzione non significa eseguirla. Definire una funzione significa semplicemente darle un nome e specificare cosa fare quando la funzione viene chiamata ( invocata ). <strong>Chiamare</strong> una funzione significa eseguire le azioni specificate, utilizzando i parametri indicati. Per esempio, se definiamo la funzione <code>square</code>, possiamo chiamarla o invocarla nel modo seguente:</p> + +<pre class="brush: js">square(5); +</pre> + +<p>Questa istruzione chiama la funzione, inviandole un argomento, il numero 5. La funzione esegue le sue istruzioni e restituisce il valore 25.</p> + +<p>Le funzioni devono essere in <em>scope</em> quando vengono chiamate, ma la dichiarazione di funzione può anche apparire sotto la chiamata, nel codice sorgente, come nell'esempio seguente:</p> + +<pre class="brush: js">console.log(square(5)); +/* ... */ +function square(n) { return n*n } +</pre> + +<p>Lo <em>scope</em> 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.</p> + +<div class="note"> +<p><strong>Nota:</strong> l'ultimo esempio funziona solo quando la funzione viene definita utilizzando la sintassi usata nell'esempio ( <code>function funcName(){}</code> ). Il codice seguente, invece, non funzionerà:</p> +</div> + +<pre class="brush: js example-bad">console.log(square(5)); +square = function (n) { + return n * n; +} +</pre> + +<p>Gli argomenti di una funzione non sono limitati alle stringhe testuali e ai numeri. È possibile passare anche interi oggetti ad una funzione. La funzione <code>show_props()</code> (definita in <a href="/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_Properties" title="https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Working_with_Objects#Objects_and_Properties">Working with objects</a>) è un esempio di funzione che riceve, come argomento, un oggetto.</p> + +<p>Una funzione può chiamare se stessa. Per esempio, ecco una funzione che calcola in modo ricorsivo i fattoriali ( molto simile alla funzione <code>fac()</code> vista poco prima in questa stessa pagina ):</p> + +<pre class="brush: js">function factorial(n){ + if ((n == 0) || (n == 1)) + return 1; + else + return (n * factorial(n - 1)); +} +</pre> + +<p>A questo punto, è possibile calcolare i fattoriali dei cinque numeri seguenti:</p> + +<pre class="brush: js">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 +</pre> + +<p>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 <a class="new" href="https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Function" title="The documentation about this has not yet been written; please consider contributing!"><code>Function</code></a>). Uno di questi metodi, <a class="new" href="https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Global_Objects/Function/apply" title="The documentation about this has not yet been written; please consider contributing!"><code>apply()</code></a>, può essere usato a questo scopo.</p> + +<h2 class="deki-transform" id="Lo_scope_di_una_funzione">Lo scope di una funzione</h2> + +<p>Alle variabili definite all'interno di una funzione non è possibile accedere dall'esterno della funzione, poichè la variabile è definita solo per lo <em>scope</em> della funzione ( <em>scope</em>: 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 <em>scope</em> in cui è stata definita. In altre parole, una funzione definita nello <em>scope</em> globale può accedere a tutte le variabili definite nello <em>scope</em> 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.</p> + +<pre class="brush: js">// Queste variabili sono definite nello <em>scope</em> globale + +var num1 = 20, + num2 = 3, + name = "Chamahk"; + +// Questa funzione è definita nello <em>scope</em> 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" +</pre> + +<h2 id="Scope_e_lo_stack_della_funzione">Scope e lo stack della funzione</h2> + +<h3 id="Ricorsione">Ricorsione</h3> + +<p>Una funzione può chiamare se stessa. Esistono tre modi per una funzione di chiamare se stessa:</p> + +<ol> + <li>il nome della funzione</li> + <li><code><a href="/en-US/docs/Web/JavaScript/Reference/Functions/arguments/callee">arguments.callee</a></code></li> + <li>una variabile <em>in-scope</em> che fa da riferimento alla funzione</li> +</ol> + +<p>Per esempio, considerate la seguente definizione di funzione:</p> + +<pre class="brush: js">var foo = function bar() { + // statements go here +}; +</pre> + +<p>All'interno del corpo della funzione, le tre seguenti istruzioni sono equivalenti:</p> + +<ol> + <li><code>bar()</code></li> + <li><code>arguments.callee()</code></li> + <li><code>foo()</code></li> +</ol> + +<p>Una funzione che chiama se stessa viene detta <em>funzione ricorsiva</em>. 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:</p> + +<pre class="brush: js">var x = 0; +while (x < 10) { // "x < 10" is the loop condition + // do stuff + x++; +} +</pre> + +<p>può essere convertito in una funzione ricorsiva e in una chiamata a quella funzione:</p> + +<pre class="brush: js">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); +</pre> + +<p>Tuttavia, alcuni algoritmi non possono essere semplici loop iterativi. Per esempio, per avere tutti i nodi di una struttura ad albero (per esempio, il <a href="/en-US/docs/DOM">DOM</a>) è molto più semplice usare la ricorsione:</p> + +<pre class="brush: js">function walkTree(node) { + if (node == null) // + return; + // do something with node + for (var i = 0; i < node.childNodes.length; i++) { + walkTree(node.childNodes[i]); + } +} +</pre> + +<p>Paragonato alla funzione <code>loop</code>, ciascuna chiamata ricorsiva, qui, esegue, a sua volta, molte chiamate ricorsive.</p> + +<p>È 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.</p> + +<p>Un comportamento paragonabile allo stack può essere visto nell'esempio seguente:</p> + +<pre class="brush: js">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</pre> + +<h3 id="Funzioni_annidate_e_chiusure">Funzioni annidate e chiusure</h3> + +<p>È 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 <em>chiusura</em> ( <em>closure )</em>. Una chiusura è un'espressione (normalmente, una funzione) che può avere variabili libere ( non locali ) legate ad un ambiente (ambiente che "chiude" l'espressione).</p> + +<p>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 <em>scope</em> ( ambiente ) della funzione esterna.</p> + +<p>Per riepilogare:</p> + +<ul> + <li>alla funzione interna possono accedere solo le istruzioni contenute nella funzione esterna.</li> +</ul> + +<ul> + <li>la funzione interna forma una chiusura: la funzione interna può utilizzare gli argomenti e le variabili della funzione esterna, mentre la funzione esterna non può utilizzare gli argomenti e le variabili della funzione interna.</li> +</ul> + +<p>Ecco un esempio di funzione annidata:</p> + +<pre class="brush: js">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 +</pre> + +<p>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:</p> + +<pre class="brush: js">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 +</pre> + +<h3 id="Persistenza_delle_variabili">Persistenza delle variabili</h3> + +<p>Da notare come <code>x</code> venga preservata anche all'uscita da <code>inside</code>. Una chiusura deve preservare argomenti e variabili in tutti gli <em>scope</em> ai quali è riferita. Poichè ogni chiamata potrebbe trasportare argomenti differenti, per ogni chiamata alla funzione <em>outside</em> viene creata una nuova chiusura. La memoria può essere liberata solo quando <code>inside</code> non è più accessibile.</p> + +<p>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.</p> + +<h3 id="Funzioni_annidate_multiple">Funzioni annidate multiple</h3> + +<p>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ù <em>scope</em>; ciascuna chiusura contiene lo <em>scope</em> delle funzioni che la contengono. Questo meccanismo è chiamato <em>scope chaining</em> ( catena di <em>scope</em> ). (Perchè è chiamata "catena" sarà chiaro tra poco.)</p> + +<p>Considerate l'esempio seguente:</p> + +<pre class="brush: js">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) +</pre> + +<p>In questo esempio, <code>C</code> accede alla variabile <code><em>y</em> di B</code> e alla <em>x</em> di <code>A</code>. Questo accade perchè:</p> + +<ol> + <li><code>B</code> forma una chiusura che include <code>A</code>: quindi, <code>B</code> può accedere agli argomenti ed alle variabili di <code>A</code>.</li> + <li><code>C</code> forma una chiusura che include <code>B</code>.</li> + <li>Poichè la chiusura di <code>B </code>include <code>A</code>, la chiusura di <code>C</code> include <code>A</code>; <code>C</code> può accedere agli argomenti ed alle variabili sia di <code>B</code> <em>che</em> di <code>A</code>. In altre parole, <code>C</code> unisce in una catena gli <em>scope</em> di <code>B</code> ed <code>A</code> in quell'ordine.</li> +</ol> + +<p>Il contrario, tuttavia, non è vero. <code>A</code> non può accedere a <code>C</code>, perchè <code>A</code> non può accedere ad alcun argomento o variabile di <code>B</code>, di cui <code>C</code> è una variabile. Quindi, <code>C</code> resta privata solo a <code>B</code>.</p> + +<h3 id="Conflitti_tra_nomi">Conflitti tra nomi</h3> + +<p>Quando due argomenti o variabili, all'interno degli <em>scope</em> di una chiusura hanno lo stesso nome, nasce un <em>conflitto tra nomi</em>. Gli <em>scope</em> più interni hanno la precedenza, così lo <em>scope</em> più annidato ha la precedenza più elevata, mentre lo <em>scope</em> più esterno ha la precedenza più bassa. Questa è la catena degli <em>scope</em>. Il primo della catena è lo <em>scope</em> più annidato, mentre l'ultimo è lo <em>scope</em> più esterno. Vediamo il seguente esempio:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">function</span> <span class="function token">outside</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> x <span class="operator token">=</span> <span class="number token">10</span><span class="punctuation token">;</span> + <span class="keyword token">function</span> <span class="function token">inside</span><span class="punctuation token">(</span>x<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">return</span> x<span class="punctuation token">;</span> + <span class="punctuation token">}</span> + <span class="keyword token">return</span> inside<span class="punctuation token">;</span> +<span class="punctuation token">}</span> +result <span class="operator token">=</span> <span class="function token">outside</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">(</span><span class="number token">20</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// returns 20 instead of 10</span></code></pre> + +<p>Il conflitto tra nomi avviene con l'istruzione <code>return x</code> ed è tra il nome del parametro <code>x di inside</code> ed il nome della variabile x di <code>outside</code>. La catena di <em>scope</em> qui è {<code>inside</code>, <code>outside</code>, global object}. Quindi, la x di <code>inside ha la precedenza sulla x di</code> <code>outside</code>: il valore restituito, alla fine, sarà 20 ( la x di <code>inside </code>) e non 10 ( la x di <code>outside </code>).</p> + +<h2 id="Closure">Closure</h2> + +<p>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 <em>scope</em> 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 <em>scope</em> esterni alla funzione esterna.</p> + +<pre class="brush: js">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 <em>scope</em> esterni +}, +myPet = pet("Vivie"); + +myPet(); // restituisce "Vivie" +</pre> + +<p>Può essere molto più complicato del codice scritto sopra. Può essere restituito un oggetto contenente metodi per manipolare le variabili interne della funzione esterna.</p> + +<pre class="brush: js">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 +</pre> + +<p>Nel codice sopra, la variabile <code>name</code> 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.</p> + +<pre class="brush: js">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 +</pre> + +<p>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 <em>scope</em> esterno, non sarà più possibile riferirsi alla variabile esterna.</p> + +<pre class="brush: js">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 ??? + } + } +} +</pre> + +<p>È davvero complicato usare la variabile magica <code>this</code> nelle closure. La variabile <code>this</code> è da usarsi con cautela, poichè ciò a cui <code>this</code> si riferisce dipende esclusivamente da dove è stata invocata la funzione, piuttosto che da dove è stata definita.</p> + +<h2 id="Usare_l'oggetto_arguments">Usare l'oggetto arguments</h2> + +<p>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:</p> + +<pre class="brush: js">arguments[i] +</pre> + +<p>dove <code>i</code> è il numero ordinale dell'argomento, a partire da zero. Così, il primo argomento passato ad una funzione sarà <code>arguments[0]</code>. Il numero totale degli argomenti è dato da <code>arguments.length</code>.</p> + +<p>Usando l'oggetto <code>arguments</code>, è 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 <code>arguments.length</code> per determinare il numero degli argomenti realmente passati alla funzione, per poi accedere a ciascuno di essi usando l'oggetto <code>arguments</code>.</p> + +<p>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ì:</p> + +<pre class="brush: js">function myConcat(separator) { + var result = "", // initialize list + i; + // iterate through arguments + for (i = 1; i < arguments.length; i++) { + result += arguments[i] + separator; + } + return result; +} +</pre> + +<p>È possibile passare una quantità qualsiasi di argomenti alla funzione e la funzione comporrà una stringa testuale contenente tutti gli argomenti passati:</p> + +<pre class="brush: js">// 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"); +</pre> + +<div class="note"> +<p><strong>Nota:</strong> La variabile <code>arguments</code> è simile ad un array ( "array-like" ), ma non è un array. È simile ad un array poichè ha un indice numerato ed una proprietà <code>length</code>. Tuttavia, non possiede tutti i metodi di manipolazione degli array.</p> +</div> + +<p>Vedi l'oggetto <a class="new" href="https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Function" title="The documentation about this has not yet been written; please consider contributing!"><code>Function</code></a> nella JavaScript reference, per avere maggiori informazioni.</p> + +<h2 id="I_parametri_di_una_funzione">I parametri di una funzione</h2> + +<p>A partire da ECMAScript 6, esistono due nuovi tipi di parametri: i parametri di <em>default</em> e i parametri <em>rest</em>.</p> + +<h3 id="I_parametri_di_default">I parametri di default</h3> + +<p>In JavaScript, i parametri di una funzione hanno come valore di default <code>undefined</code>. Tuttavia, in alcune situazioni potrebbe essere utile impostare un diverso valore di default. In questo, possono aiutare i parametri di default.</p> + +<p>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 <code>undefined</code>. Se nell'esempio seguente non venisse passato, durante la chiamata, alcun valore per <code>b</code>, il suo valore sarebbe <code>undefined</code>, anche quando venisse valutata l'istruzione <code>a*b</code>, e la chiamata a <code>multiply</code> restituirebbe <code>NaN ( Not a Number )</code>. Tuttavia, questo valore viene definito nella seconda riga:</p> + +<pre class="brush: js">function multiply(a, b) { + b = typeof b !== 'undefined' ? b : 1; + + return a*b; +} + +multiply(5); // 5 +</pre> + +<p>Con i parametri di deafult, la verifica all'interno del corpo della funzione non è più necessaria. Ora, è possibile mettere <code>1</code> come valore di default per <code>b</code> nella dichiarazione della funzione:</p> + +<pre class="brush: js">function multiply(a, b = 1) { + return a*b; +} + +multiply(5); // 5</pre> + +<p>Per maggiori dettagli, vedi <a href="/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters">paremetri di default</a> nella Javascript reference.</p> + +<h3 id="I_parametri_Rest">I parametri Rest</h3> + +<p>La sintassi dei <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters">rest parameter</a> permette di rappresentare un indefinito numero di argomenti come un array. Nell'esempio, usiamo i parametri <em>rest</em> 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.</p> + +<pre class="brush: js">function multiply(multiplier, ...theArgs) { + return theArgs.map(x => multiplier * x); +} + +var arr = multiply(2, 1, 2, 3); +console.log(arr); // [2, 4, 6]</pre> + +<h2 id="Le_funzioni_a_freccia">Le funzioni a freccia</h2> + +<p>Una <a href="/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions">espressione di funzione a freccia</a> ( nota anche come <strong>fat arrow function </strong>) ha una sintassi più stringata rispetto alle espressioni di funzione e forza, lessicalmente, il valore di <code>this</code>. Le funzioni a freccia sono sempre anonime. Vedi anche il post di hacks.mozilla.org: "<a href="https://hacks.mozilla.org/2015/06/es6-in-depth-arrow-functions/">ES6 In Depth: Arrow functions</a>".</p> + +<p>Sono due i fattori che influenzarono l'introduzione delle funzioni a freccia: la brevità delle funzioni ed il <code>this</code> lessicale.</p> + +<h3 id="Funzioni_più_brevi">Funzioni più brevi</h3> + +<p>In alcuni modelli funzionali, funzioni più brevi sono le benvenute. Paragoniamo le due istruzioni seguenti:</p> + +<pre class="brush: js">var a = [ + "Hydrogen", + "Helium", + "Lithium", + "Beryllium" +]; + +var a2 = a.map(function(s){ return s.length }); +var a3 = a.map( s => s.length );</pre> + +<h3 id="Il_this_lessicale">Il <code>this lessicale</code></h3> + +<p>Until arrow functions, every new function defined its own <a href="/en-US/docs/Web/JavaScript/Reference/Operators/this">this</a> 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.</p> + +<pre class="brush: js">function Person() { + // The Person() constructor defines `<code>this`</code> 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();</pre> + +<p>In ECMAScript 3/5, this issue was fixed by assigning the value in <code>this</code> to a variable that could be closed over.</p> + +<pre class="brush: js">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); +}</pre> + +<p>Alternatively, a <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind">bound function</a> could be created so that the proper <code>this</code> value would be passed to the <code>growUp()</code> function.</p> + +<p>Arrow functions capture the <code>this</code> value of the enclosing context, so the following code works as expected.</p> + +<pre class="brush: js">function Person(){ + this.age = 0; + + setInterval(() => { + this.age++; // |this| properly refers to the person object + }, 1000); +} + +var p = new Person();</pre> + +<h2 id="Predefined_functions">Predefined functions</h2> + +<p>JavaScript has several top-level, built-in functions:</p> + +<dl> + <dt>{{jsxref("Global_Objects/eval", "eval()")}}</dt> + <dd> + <p>The <code><strong>eval()</strong></code> method evaluates JavaScript code represented as a string.</p> + </dd> + <dt>{{jsxref("Global_Objects/uneval", "uneval()")}} {{non-standard_inline}}</dt> + <dd> + <p>The <code><strong>uneval()</strong></code> method creates a string representation of the source code of an {{jsxref("Object")}}.</p> + </dd> + <dt>{{jsxref("Global_Objects/isFinite", "isFinite()")}}</dt> + <dd> + <p>The global <code><strong>isFinite()</strong></code> function determines whether the passed value is a finite number. If needed, the parameter is first converted to a number.</p> + </dd> + <dt>{{jsxref("Global_Objects/isNaN", "isNaN()")}}</dt> + <dd> + <p>The <code><strong>isNaN()</strong></code> function determines whether a value is {{jsxref("Global_Objects/NaN", "NaN")}} or not. Note: coercion inside the <code>isNaN</code> function has <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isNaN#Description">interesting</a> rules; you may alternatively want to use {{jsxref("Number.isNaN()")}}, as defined in ECMAScript 6, or you can use <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/typeof">typeof</a></code> to determine if the value is Not-A-Number.</p> + </dd> + <dt>{{jsxref("Global_Objects/parseFloat", "parseFloat()")}}</dt> + <dd> + <p>The <code><strong>parseFloat()</strong></code> function parses a string argument and returns a floating point number.</p> + </dd> + <dt>{{jsxref("Global_Objects/parseInt", "parseInt()")}}</dt> + <dd> + <p>The <code><strong>parseInt()</strong></code> function parses a string argument and returns an integer of the specified radix (the base in mathematical numeral systems).</p> + </dd> + <dt>{{jsxref("Global_Objects/decodeURI", "decodeURI()")}}</dt> + <dd> + <p>The <code><strong>decodeURI()</strong></code> function decodes a Uniform Resource Identifier (URI) previously created by {{jsxref("Global_Objects/encodeURI", "encodeURI")}} or by a similar routine.</p> + </dd> + <dt>{{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent()")}}</dt> + <dd> + <p>The <code><strong>decodeURIComponent()</strong></code> method decodes a Uniform Resource Identifier (URI) component previously created by {{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}} or by a similar routine.</p> + </dd> + <dt>{{jsxref("Global_Objects/encodeURI", "encodeURI()")}}</dt> + <dd> + <p>The <code><strong>encodeURI()</strong></code> 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).</p> + </dd> + <dt>{{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent()")}}</dt> + <dd> + <p>The <code><strong>encodeURIComponent()</strong></code> 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).</p> + </dd> + <dt>{{jsxref("Global_Objects/escape", "escape()")}} {{deprecated_inline}}</dt> + <dd> + <p>The deprecated <code><strong>escape()</strong></code> 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.</p> + </dd> + <dt>{{jsxref("Global_Objects/unescape", "unescape()")}} {{deprecated_inline}}</dt> + <dd> + <p>The deprecated <code><strong>unescape()</strong></code> 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 <code>unescape()</code> is deprecated, use {{jsxref("Global_Objects/decodeURI", "decodeURI()")}} or {{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent")}} instead.</p> + </dd> +</dl> + +<p>{{PreviousNext("Web/JavaScript/Guide/Loops_and_iteration", "Web/JavaScript/Guide/Expressions_and_Operators")}}</p> diff --git a/files/it/web/javascript/guida/grammar_and_types/index.html b/files/it/web/javascript/guida/grammar_and_types/index.html new file mode 100644 index 0000000000..2a43d5230d --- /dev/null +++ b/files/it/web/javascript/guida/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 +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Introduction", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}</div> + +<p class="summary">Questo capitolo tratta la sintassi di base di JavaScript, le dichiarazioni di variabili, i tipi di dati e i letterali.</p> + +<h2 id="Nozioni_di_base">Nozioni di base</h2> + +<p>JavaScript mutua molta della sua sintassi da Java, ma è anche influenzato da Awk, Perl e Python.</p> + +<p>JavaScript è sensibile al maiuscolo-minuscolo (<strong>case-sensitive</strong>) e usa l'insieme di caratteri <strong>Unicode</strong>.</p> + +<p>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 (<a href="/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Automatic_semicolon_insertion">ASI</a>) 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 <a href="/en-US/docs/Web/JavaScript/Reference/Lexical_grammar">lexical grammar</a> di JavaScript.</p> + +<h2 id="Commenti">Commenti</h2> + +<p>La sintassi dei <strong>commenti</strong> è la stessa di quelli del C++ e di molti altri linguaggi:</p> + +<pre class="brush: js">// una linea di commento + +/* questo è un commento più lungo, + occupa più linee + */ + +/* Però non puoi /* annidare i commenti */ SyntaxError */</pre> + +<h2 id="Dichiarazioni">Dichiarazioni</h2> + +<p>Ci sono tre tipi di dichiarazioni in JavaScript.</p> + +<dl> + <dt>{{jsxref("Statements/var", "var")}}</dt> + <dd>Dichiarazione di una variabile, opzionalmente inizializzata ad un valore.</dd> + <dt>{{experimental_inline}} {{jsxref("Statements/let", "let")}}</dt> + <dd>Dichiarazione di una variabile locale con visibilità nel blocco, opzionalmente inizializzata ad un valore.</dd> + <dt>{{experimental_inline}} {{jsxref("Statements/const", "const")}}</dt> + <dd>Dichiarazione di una costante in sola lettura con un nome.</dd> +</dl> + +<h3 id="Variabili">Variabili</h3> + +<p>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.</p> + +<p>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).</p> + +<p>Si possono usare anche le lettere ISO 8859-1 o Unicode come per esempio å e ü negli identificatori. Possono essere usate anche le <a href="/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#String_literals">sequenze di escape di Unicode</a> come caratteri negli identificatori.</p> + +<p>Alcuni esempi di nomi leciti sono <code>Number_hits</code>, <code>temp99</code> e <code>_name</code>.</p> + +<h3 id="Dichiarazione_di_variabili">Dichiarazione di variabili</h3> + +<p>Una variabile può essere dichiarata in tre modi:</p> + +<ul> + <li>Con la parola chiave {{jsxref("Statements/var", "var")}}, per esempio, <code>var x = 42</code>. Questa sintassi può essere usata per dichiarare sia variabili locali che globali.</li> + <li>Semplicemente assegnandole un valore. Per esempio, <code>x = 42</code>. questo dichiara sempre una variabile globale. Genera uno warning nella modalità strict di JavaScript. Questa variante non dovrebbe essere usata.</li> + <li>Con la parola chiave {{jsxref("Statements/let", "let")}}, ad esempio, <code>let y = 13</code>. Questa sintassi può essere usata per dichiarare una variabile locale visibile in un blocco. Vedi <a href="#Variable_scope">Visibilità delle variabili</a> più in basso.</li> +</ul> + +<h3 id="Valutazione_delle_variabili">Valutazione delle variabili</h3> + +<p>Una variabile dichiarata usando le istruzioni <code>var</code> o <code>let</code> senza nessun valore iniziale specificato ha il valore {{jsxref("undefined")}}.</p> + +<p>Il tentativo di accedere ad una variabile non dichiarata o di accedere ad un identificatore dichiarato con l'istruzione <code>let,</code> prima di una sua inizializzazione, provocherà un'eccezione di {{jsxref("ReferenceError")}}:</p> + +<pre class="brush: js">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 + +<code>console.log("Il valore di c è " + c); // </code>Scrive nel log "<code>Il valore di c è undefined" </code> +<code>var c; + +console.log("Il valore di x è " + x); // </code>Solleva una eccezione<code> ReferenceError: x is not defined +let x;</code></pre> + +<p>Si può usare <code>undefined</code> per determinare se una variabile ha un valore oppure no. Nel codice seguente alla variabile <code>input</code> non è stato assegnato un valore e la condizione dell'istruzione <code><a href="/en-US/docs/Web/JavaScript/Reference/Statements/if...else" title="en-US/docs/JavaScript/Reference/Statements/if...else">if</a></code> è</p> + +<p>valuta a <code>true</code>.</p> + +<pre class="brush: js">var input; +if(input === undefined){ + faiQuesto(); +} else { + faiQuello(); +} +</pre> + +<p>Il valore <code>undefined</code> si comporta come <code>false</code> quando viene usato in un contesto booleano. Ad esempio il codice seguente esegue la funzione <code>miaFunzione</code> perché l'elemento di <code>mioArray</code> non è definito:</p> + +<pre class="brush: js">var mioArray = []; +if (!mioArray[0]) miaFunzione(); +</pre> + +<p>Il valore <code>undefined</code> viene convertito in <code>NaN</code> quando viene usato in un contesto numerico.</p> + +<pre class="brush: js">var a; +a + 2; // Viene valutato a NaN</pre> + +<p>Quando viene valutata una variabile {{jsxref("null")}}, il valore null si comporta come 0 in un contesto numerico e <code>false </code>in un contesto booleano. Per esempio:</p> + +<pre class="brush: js">var n = null; +console.log(n * 32); // Visualizzera nella console 0 +</pre> + +<h3 id="Visibilità_delle_variabili">Visibilità delle variabili</h3> + +<p>Quando una variabile viene dichiarata fuori da una qualsiasi funzione viene chiamata variabile <em>globale</em>, poiché è disponibile in tutto il codice nel documento corrente. Quando invece la variabile viene dichiarata in una funzione viene chiamata variabile <em>locale</em>, perché è disponibile soltanto all'interno di quella funzione.</p> + +<p>JavaScript prima di ECMAScript 2015 non aveva una visibilità a <a href="/en-US/docs/Web/JavaScript/Guide/Control_flow_and_error_handling#Block_statement" title="en-US/docs/Web/JavaScript/Guide/Control_flow_and_error_handling#Block_statement">livello di blocco</a>; piuttosto una variabile dichiarata all'interno di un blocco era locale alla <em>funzione (o al contesto globale)</em> in cui il blocco risiedeva. Per esempio il seguente codice scriverà nel log 5, perché la visibilità di <code>x</code> è la funzione (o il contesto globale) all'interno del quale <code>x</code> viene dichiarata e non il blocco, che in questo caso è l'istruzione <code>if</code>.</p> + +<pre class="brush: js">if (true) { + var x = 5; +} +console.log(x); // 5 +</pre> + +<p>Il comportamento cambia quando si usa l'istruzione <code>let</code> introdotta in ECMAScript 2015.</p> + +<pre class="brush: js">if (true) { + let y = 5; +} +console.log(y); // ReferenceError: y non è definita +</pre> + +<h3 id="Sollevamento_delle_variabili">Sollevamento delle variabili</h3> + +<p>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 (<strong>hoisting</strong>); 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 <code>undefined</code>. Dunque se viene usata (o si fa riferimento ad) una variabile prima che venga dichiarata questa ritornà <code>undefined</code>.</p> + +<pre class="brush: js">/** + * 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"; +})(); +</pre> + +<p>L'esempio sopra sarà interpretato nello stesso modo di:</p> + +<pre class="brush: js">/** + * 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"; +})(); +</pre> + +<p>Per via dell'innalzamento, tutte le istruzioni <code>var</code> 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.</p> + +<p>In ECMAScript 2015, <code>let (const)</code> <strong>non solleverà/sposterà</strong> 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.</p> + +<pre><code>console.log(x); // Solleverà un'eccezione ReferenceError +let x = 3</code></pre> + +<h3 id="Sollevamento_delle_Funzioni">Sollevamento delle Funzioni</h3> + +<p>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.</p> + +<pre><code>/* Function declaration */ + +foo(); // "bar" + +function foo() { + console.log("bar"); +} + + +/* Function expression */ + +baz(); // TypeError: baz is not a function + +var baz = function() { + console.log("bar2"); +};</code></pre> + +<h3 id="Variabli_globali">Variabli globali</h3> + +<p>Le variabili globali sono in effetti proprietà dell'<em>oggetto globale</em>. Nelle pagine web l'oggetto globale è {{domxref("window")}} quindi è possibile impostare e accedere alle variabili globali usando la sintassi <code>window.<em>variabile</em></code>.</p> + +<p>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 <code>numeroDiTelefono</code> è dichiarata in un documento, è possibile far riferimento a questa variabile dall'interno di un iframe come <code>parent.numeroDiTelefono</code>.</p> + +<h3 id="Costanti">Costanti</h3> + +<p>È 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.</p> + +<pre class="brush: js">const PI = 3.14; +</pre> + +<p>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.</p> + +<p>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 <code>let</code>. Se la parola chiave <code>const</code> viene omessa si assume che l'identificatore rappresenta una variabile.</p> + +<p>Non è possibile dichiarare una costante con lo stesso nome di una funzione o di una variabile nello stesso spazio di visibilità. Per esempio:</p> + +<pre class="brush: js">// QUESTO CAUSERÀ UN ERRORE +function f() {}; +const f = 5; + +// ANCHE QUESTO CAUSERÀ UN ERRORE +function f() { + const g = 5; + var g; + + //istruzioni +} +</pre> + +<h2 id="Strutture_dati_e_tipi">Strutture dati e tipi</h2> + +<h3 id="Tipi_di_dato">Tipi di dato</h3> + +<p>L'ultimo standard ECMAScript definisce sette tipi di dati:</p> + +<ul> + <li>Sei tipi di dato che sono {{Glossary("Primitive", "primitives")}}: + <ul> + <li>{{Glossary("Boolean")}}. <code>true</code> e <code>false</code>.</li> + <li>{{Glossary("null")}}. Una parola chiave che denota un valore nullo. Siccome JavaScript è case-sensitive, <code>null</code> non è lo stesso di <code>Null</code>, <code>NULL</code>, o qualsiasi altra variante.</li> + <li>{{Glossary("undefined")}}. Una proprietà top-level il cui valore non è stato definito.</li> + <li>{{Glossary("Number")}}. <code>42</code> oppure <code>3.14159</code>.</li> + <li>{{Glossary("String")}}. "Salve"</li> + <li>{{Glossary("Symbol")}} (nuovo in ECMAScript 2015). Un tipo di dato la cui istanza è unica e immutabile.</li> + </ul> + </li> + <li>e {{Glossary("Object")}}</li> +</ul> + +<p>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.</p> + +<h3 id="Conversione_dei_tipi_dei_dati">Conversione dei tipi dei dati</h3> + +<p>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:</p> + +<pre class="brush: js">var risposta = 42; +</pre> + +<p>E più avanti è possibile assegnare alla stessa variabile un valore testo (stringa), per esempio:</p> + +<pre class="brush: js">risposta = "Grazie per tutti i pesci..."; +</pre> + +<p>Poiché in JavaScript i tipi si assegnano dinamicamente questa assegnazione non causerà un messaggio di errore.</p> + +<p>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:</p> + +<pre class="brush: js">x = "La risposta è " + 42 // "La risposta è 42" +y = 42 + " è la risposta" // "42 è la risposta" +</pre> + +<p>In istruzioni che coinvolgono altri operatori JavaScript non converte valori numerici in stringa. Per esempio:</p> + +<pre class="brush: js">"37" - 7 // 30 +"37" + 7 // "377" +</pre> + +<h3 id="Conversione_delle_stringhe_in_numeri">Conversione delle stringhe in numeri</h3> + +<p>Nel caso in cui il valore che rappresenta un numero è memorizzato come stringa ci sono dei metodi per eseguire la conversione:</p> + +<ul> + <li id="parseInt()_and_parseFloat()">{{jsxref("parseInt", "parseInt()")}}</li> + <li>{{jsxref("parseFloat", "parseFloat()")}}</li> +</ul> + +<p><code>parseInt</code> ritornerà soltanto numeri interi, ha una utilità ridotta per i numeri decimali. In aggiunta è buona pratica nell'uso di <code>parseInt</code> includere il parametro base, questo parametro è usato per specificare quale sistema di numerazione deve essere usato.</p> + +<p>Un metodo alternativo per recuperare un numero da un testo è di usare l'operatore + (più unario):</p> + +<pre class="brush: js">"1.1" + "1.1" = "1.11.1" +(+"1.1") + (+"1.1") = 2.2 +// Note: le parentesi sono aggiunte per chiarezza, non sono richieste.</pre> + +<h2 id="Letterali">Letterali</h2> + +<p>I letterali sono usati per rappresentare i valori in JavaScript. Questi sono valori fissati, non variabili, che venvono <em>letteralmente</em> inseriti nello script. Questa sezione descrive i seguenti tipi di letterali:</p> + +<ul> + <li>{{anch("Letterali di array")}}</li> + <li>{{anch("Letterali di booleani")}}</li> + <li>{{anch("Letterali di numeri in virgola-mobile")}}</li> + <li>{{anch("Letterali di numeri Interi")}}</li> + <li>{{anch("Letterali di oggeti")}}</li> + <li>{{anch("Letterali di RegExp")}}</li> + <li>{{anch("Letterali di stringhe")}}</li> +</ul> + +<h3 id="Letterali_di_array">Letterali di array</h3> + +<p>Un letterale di array è un elenco di zero o più espressioni ognuna delle quali rappresenta un elemento dell'array, inclusa in parentesi quadre (<code>[]</code>). 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.</p> + +<p>Il seguente esempio crea un array <code>tipiDiCaffe</code> con tre elementi e una lunghezza di tre:</p> + +<pre class="brush: js">var tipiDiCaffe = ["French Roast", "Colombian", "Kona"]; +</pre> + +<div class="note"> +<p><strong>Nota:</strong> Un letterale di array è un tipo di inizializzatore di oggetto. Vedi <a href="/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Using_object_initializers" title="en-US/docs/JavaScript/Guide/Working with Objects#Using Object Initializers">Usando inizializzatori di Oggett</a>i.</p> +</div> + +<p>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.</p> + +<p>Gli array letterali sono anche oggetti <code>Array</code>. Si veda {{jsxref("Array")}} e <a href="/en-US/docs/Web/JavaScript/Guide/Indexed_collections">Collezione indicizzata</a> per i dettagli sugli oggetti <code>Array</code>.</p> + +<h4 id="Virgole_aggiuntive_negli_array_letterali">Virgole aggiuntive negli array letterali</h4> + +<p>Non è obbligatorio specificare tutti gli elementi in un array letterale. Mettendo due virgole in fila l'array viene creato con il valore <code>undefined</code> per gli elementi non specificati. Il seguente esempio crea l'array <code>pesce</code>:</p> + +<pre class="brush: js">var pesce = ["Leone", , "Angelo"]; +</pre> + +<p>Questo array ha due elementi con un valore e un elemento vuoto (<code>pesce[0]</code> is "Leone", <code>pesce[1]</code> è <code>undefined</code>, e <code>pesce[2]</code> è "Angelo").</p> + +<p>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 <code>miaLista[3]</code>. Tutte le altre virgole nell'elenco indicano un elemento nuovo.</p> + +<div class="note"> +<p><strong>Nota:</strong> Le virgole in coda possono creare errori nelle versioni più vecchie dei browser ed è buona pratica rimuoverle.</p> +</div> + +<pre class="brush: js">var miaLista = ['casa', , 'scuola', ]; +</pre> + +<p>Nel seguente esempio la lunghezza dell'array è quattro e <code>miaLista[0]</code> e <code>mialista[2]</code> sono mancanti.</p> + +<pre class="brush: js">var miaLista = [ , 'casa', , 'scuola']; +</pre> + +<p>Nel seguente esempio la lunghezza dell'array è quattro e <code>mialista[1]</code> e <code>miaLista[3]</code> sono mancanti. Soltanto l'ultima virgola viene ignorata.</p> + +<pre class="brush: js">var miaLista = ['casa', , 'scuola', , ]; +</pre> + +<p>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 <code>undefined</code>, questo migliorerà la chiarezza e la manutenibilità del codice.</p> + +<h3 id="Letterali_di_booleani">Letterali di booleani</h3> + +<p>Il tipo Boolean ha due valori letterali: <code>true</code> e <code>false</code>.</p> + +<p>Non vanno confusi i valori primitivi Booleani <code>true</code> e <code>false</code> 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.</p> + +<h3 id="Letterali_di_numeri_Interi">Letterali di numeri Interi</h3> + +<p>Gli interi possono essere rappresentati in decimale (base 10), esadecimale (base 16), ottale (base 8) e binario (base 2).</p> + +<ul> + <li>I letterali decimali interi sono formati da una sequenza di cifre senza uno 0 (zero) iniziale.</li> + <li>0 (zero) iniziali in un letterale intero, o un iniziale 0o (o 0O) indicano che il numero è in ottale. Gli interi ottali possono includere soltanto le cifre 0-7.</li> + <li>Un iniziale 0x (o 0X) indica l'esadecimale. Interi esadecimali possono includere le cifre (0-9) e le lettere a-f e A-F.</li> + <li> + <p>Un iniziale 0b (o 0B) indica il binario. Gli interi binari possono includere soltanto le cifre 0 e 1.</p> + </li> +</ul> + +<p>Alcuni esempi i di letterali di interi sono:</p> + +<pre class="eval">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) +</pre> + +<p>Per maggiori informazioni, vedi <a href="/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Numeric_literals">Numeric literals in the Lexical grammar reference</a>.</p> + +<h3 id="Letterali_di_numeri_in_virgola-mobile">Letterali di numeri in virgola-mobile</h3> + +<p>Un letterale per un numero in virgola mobile può avere le seguenti parti:</p> + +<ul> + <li>Un intero in base dieci che può avere un segno (cioè può essere preceduto da "+" o "-"),</li> + <li>Un punto decimale ("."),</li> + <li>Una parte decimale (un altro numero in base dieci),</li> + <li>Un esponente.</li> +</ul> + +<p>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").</p> + +<p>Più concisamente la sintassi è:</p> + +<pre class="eval">[(+|-)][cifre][.cifre][(E|e)[(+|-)]cifre] +</pre> + +<p>Per esempio:</p> + +<pre class="eval">3.1415926 +-.123456789 +-3.1E+12 +.1e-23 +</pre> + +<h3 id="Letterali_di_oggetti">Letterali di oggetti</h3> + +<p>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 (<code>{}</code>). 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é <code>{</code> sarà interpretata come l'inizio di un blocco.</p> + +<p>Quello seguente è un esempio di un letterale di un oggetto. Il primo elemento dell'oggetto <code>automobile</code> definisce un proprietà, <code>miaAutomobile</code>, e gli assegna il testo "<code>Saturn</code>"; il secondo elemento, la proprietà <code>getAutomobile</code>, è immediatamente assegnata al valore risultante dall'invocazione della funzione <code>(tipiDiAutomobile("Honda"));</code> il terzo elemento, la proprietà <code>speciale</code>, usa una variabile esistente (<code>saldi</code>).</p> + +<pre class="brush: js">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 +</pre> + +<p>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.</p> + +<pre class="brush: js">var automobile = { molteAutomobili: {a: "Saab", "b": "Jeep"}, 7: "Mazda" }; + +console.log(automobile.molteAutomobili.b); // Jeep +console.log(automobile[7]); // Mazda +</pre> + +<p>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 (<code>.</code>), potranno però essere acceduti e impostati usando la notazione analoga a quella degli array ("<code>[]</code>").</p> + +<pre class="brush: js">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!</pre> + +<p>In ES2015, i letterali di oggetti sono estesi per supportare l'impostazione del prototipo al momento della costruzione, forme abbreviate per le assegnazioni tipo <code>foo: foo</code>, 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.</p> + +<pre class="brush: js">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 +};</pre> + +<p>Nota che:</p> + +<pre class="brush: js">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 +</pre> + +<h3 id="Letterali_di_RegExp">Letterali di RegExp</h3> + +<p>Un letterale di espressione regolare (RegExp) è un modello (pattern) racchiuso tra barre. il seguente è un esempio di un letterale di una espressione regolare.</p> + +<pre class="brush: js">var re = /ab+c/;</pre> + +<h3 id="Letterali_di_stringhe">Letterali di stringhe</h3> + +<p>Un letterale di testo (stringa nel preguo del testo) è formato da zero o più caratteri racchiusi tra virgolette doppie (<code>"</code>) o singole (<code>'</code>). 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:</p> + +<pre class="brush: js">"foo" +'bar' +"1234" +"una linea \n altra linea" +"prima dell'una" +</pre> + +<p>È 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à <code>String.length</code> con una stringa letterale:</p> + +<pre class="brush: js">console.log("John's cat".length) +// Stamperà il numero di simboli nel testo inclusi gli spazi. +// In questo caso 10. +</pre> + +<p>In ES2015 sono disponibili i letterali modello. I letterali modello sono racchiusi tra accenti gravi (` `) (<a href="http://en.wikipedia.org/wiki/Grave_accent" rel="noopener">accento grave</a>) 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.</p> + +<pre class="brush: js">// 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);</pre> + +<p>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 <code>String</code>.</p> + +<h4 id="Uso_di_caratteri_speciali_nelle_stringhe">Uso di caratteri speciali nelle stringhe</h4> + +<p>Oltre ai caratteri ordinari si possono includere anche dei caratteri speciali nelle stringhe come mostrato nel seguente esempio.</p> + +<pre class="brush: js">"prima linea \n seconda linea" +</pre> + +<p>La seguente tabella elenca i caratteri speciali che possono essere usati nelle stringhe JavaScript.</p> + +<table class="standard-table"> + <caption>Table: JavaScript caratteri speciali</caption> + <thead> + <tr> + <th scope="col">Carattere</th> + <th scope="col">Significato</th> + </tr> + </thead> + <tbody> + <tr> + <td><code>\0</code></td> + <td>Byte null</td> + </tr> + <tr> + <td><code>\b</code></td> + <td>Backspace</td> + </tr> + <tr> + <td><code>\f</code></td> + <td>Form feed</td> + </tr> + <tr> + <td><code>\n</code></td> + <td>New line</td> + </tr> + <tr> + <td><code>\r</code></td> + <td>Carriage return</td> + </tr> + <tr> + <td><code>\t</code></td> + <td>Tab</td> + </tr> + <tr> + <td><code>\v</code></td> + <td>Tab verticale</td> + </tr> + <tr> + <td><code>\'</code></td> + <td>Apostrofo o virgoletta singola</td> + </tr> + <tr> + <td><code>\"</code></td> + <td>Virgoletta doppia</td> + </tr> + <tr> + <td><code>\\</code></td> + <td>Il carattere backslash</td> + </tr> + <tr> + <td><code>\<em>XXX</em></code></td> + <td>Il carattere con la codifica Latin-1 specificata da fino a tre caratteri <em>XXX</em> tra 0 e 377. Per esempio \251 è la sequenza ottale per il simbolo di copyright.</td> + </tr> + <tr> + </tr> + <tr> + <td><code>\x<em>XX</em></code></td> + <td>Il carattere con la codifica Latin-1 specificata da due cifre esadecimali <em>XX</em> comprese tra 00 e FF. Per esempio \xA9 è la sequenza ottale per il simbolo di copyright.</td> + </tr> + <tr> + </tr> + <tr> + <td><code>\u<em>XXXX</em></code></td> + <td>Il carattere Unicode specificato da quattro cifre esadecimali <em>XXXX</em>. Per esempio \u00A9 è la sequenza Unicode per il simbolo di copyright. Vedi <a href="/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#String_literals">Unicode escape sequences</a>.</td> + </tr> + <tr> + <td><code>\u<em>{XXXXX}</em></code></td> + <td>Escape per Unicode code point. Per esempio \u{2F804} è la stessa cosa dell'esape semplice Unicode \uD87E\uDC04.</td> + </tr> + </tbody> +</table> + +<h4 id="Caratteri_a_cui_aggiungere_il_backslash_(Escaping)">Caratteri a cui aggiungere il backslash (Escaping)</h4> + +<p>Per i caratteri non elencati nella tabella un backslash (\) prefisso viene ignorato, questo uso è deprecato e devrebbe essere evitato.</p> + +<p>Le virgolette possono essere inserite in una stringa precedendole da un backslash. Questo è noto come <em>escaping</em> delle virgolette. Per esempio:</p> + +<pre class="brush: js">var quote = "Lui legge \"The Cremation of Sam McGee\" by R.W. Service."; +console.log(quote); +</pre> + +<p>Il risultato sarebbe:</p> + +<pre class="eval">Lui legge "The Cremation of Sam McGee" by R.W. Service. +</pre> + +<p>Per includere un backslash in una stringa va fatto l'esape del carattere backslash. Per esempio, per assegnare il percorso <code>c:\temp</code> ad una stringa, usare il seguente:</p> + +<pre class="brush: js">var home = "c:\\temp"; +</pre> + +<p>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.</p> + +<pre class="brush: js">var str = "questa stringa \ +è spezzata \ +attraverso multiple\ +linee." +console.log(str); // questa stringa è spezzata attraverso multiple linee. +</pre> + +<p>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:</p> + +<pre class="brush: js">var poem = +"Roses are red,\n\ +Violets are blue.\n\ +I'm schizophrenic,\n\ +And so am I." +</pre> + +<h2 id="Ulteriori_informazioni">Ulteriori informazioni</h2> + +<p>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:</p> + +<ul> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Control_flow_and_error_handling">Controllo del flusso e gestione errori</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration">Cicli e iterazioni</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions">Funzioni</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators">Espresioni e operatori</a></li> +</ul> + +<p>Nel prossimo capitolo, tratteremo i costrutti del controllo del flusso e la gestione degli errori.</p> + +<p>{{PreviousNext("Web/JavaScript/Guide/Introduction", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}</p> diff --git a/files/it/web/javascript/guida/index.html b/files/it/web/javascript/guida/index.html new file mode 100644 index 0000000000..ba956f21f2 --- /dev/null +++ b/files/it/web/javascript/guida/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 +--- +<div>{{jsSidebar("JavaScript Guide")}}</div> + +<p class="summary">La Guida JavaScript mostra come utilizzare <a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript">JavaScript</a> e offre una panoramica del linguaggio. Se hai bisogno di informazioni esaustive su una sua funzione, dai un'occhiata alle <a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Reference">reference JavaScript</a>.</p> + +<h2 id="Capitoli">Capitoli</h2> + +<p>Questa guida è divisa in vari capitoli:</p> + +<ul class="card-grid"> + <li><span><a href="/en-US/docs/Web/JavaScript/Guide/Introduction">Introduzione</a></span> + + <p><a href="/en-US/docs/Web/JavaScript/Guide/Introduction#Where_to_find_JavaScript_information">A proposito di questa guida</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Introduction#What_is_JavaScript">A proposito di JavaScript</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Introduction#JavaScript_and_Java">JavaScript e Java</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Introduction#JavaScript_and_the_ECMAScript_Specification">ECMAScript</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Introduction#Getting_started_with_JavaScript">Strumenti</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Introduction#Hello_world">Hello World</a></p> + </li> + <li><span><a href="/en-US/docs/Web/JavaScript/Guide/Grammar_and_types">Grammatica & Tipi</a></span> + <p><a href="/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Basics">Sintassi base e commenti</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Declarations">Dichiarazioni</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Variable_scope">Scope delle variabili</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Variable_hoisting">Hoisting delle variabili</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Data_structures_and_types">Strutture Dati e Tipi</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#Literals">Letterali</a></p> + </li> + <li><span><a href="https://wiki.developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Control_flow_and_error_handling">Controllo di flusso & gestione degli errori</a></span> + <p><code><a href="/en-US/docs/Web/JavaScript/Guide/Control_flow_and_error_handling#if...else_statement">if...else</a></code><br> + <code><a href="/en-US/docs/Web/JavaScript/Guide/Control_flow_and_error_handling#switch_statement">switch</a></code><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Control_flow_and_error_handling#Exception_handling_statements"><code>try</code>/<code>catch</code>/<code>throw</code></a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Control_flow_and_error_handling#Utilizing_Error_objects">Oggetto Error</a></p> + </li> + <li><span><a href="/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration">Cicli & Iterazioni</a></span> + <p><code><a href="/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration#for_statement">for</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration#while_statement">while</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration#do...while_statement">do...while</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration#break_statement">break</a>/<a href="/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration#continue_statement">continue</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration#for...in_statement">for..in</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration#for...of_statement">for..of</a></code></p> + </li> +</ul> + +<ul class="card-grid"> + <li><span><a href="/en-US/docs/Web/JavaScript/Guide/Functions">Funzioni</a></span> + + <p><a href="/en-US/docs/Web/JavaScript/Guide/Functions#Defining_functions">Definire le funzioni</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Functions#Calling_functions">Chiamare le funzioni </a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Functions#Function_scope">Scope delle funzioni</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Functions#Closures">Closure</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Functions#Using_the_arguments_object">Argomenti</a> & <a href="/en-US/docs/Web/JavaScript/Guide/Functions#Function_parameters">Parametri</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Functions#Arrow_functions">Funzioni freccia</a></p> + </li> + <li><span><a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators">Espressioni & operatori</a></span> + <p><a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Assignment_operators">Assegnamento</a> & <a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Comparison_operators">Comparazione</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Arithmetic_operators">Operatori aritmetici</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Bitwise_operators">Operatori di bitwise</a> & <a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Logical_operators">logici</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Conditional_(ternary)_operator">Operatore (ternario) condizionale</a></p> + </li> + <li><span><a href="/en-US/docs/Web/JavaScript/Guide/Numbers_and_dates">Numeri & Date</a></span><a href="/en-US/docs/Web/JavaScript/Guide/Numbers_and_dates#Numbers"> Numeri come letterali</a> + <p><a href="/en-US/docs/Web/JavaScript/Guide/Numbers_and_dates#Number_object">Oggetto <code>Number</code></a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Numbers_and_dates#Math_object">Oggetto <code>Math</code></a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Numbers_and_dates#Date_object">Oggetto <code>Date</code></a></p> + </li> + <li><span><a href="/en-US/docs/Web/JavaScript/Guide/Text_formatting">Formattazione di testi</a></span> + <p><a href="/en-US/docs/Web/JavaScript/Guide/Text_formatting#String_literals">Stringhe come letterali</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Text_formatting#String_objects">Oggetto <code>String</code></a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Text_formatting#Multi-line_template_literals">Template stringhe come letterali</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Text_formatting#Internationalization">Internazionalizzazione</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Regular_Expressions">Espressioni Regolari</a></p> + </li> +</ul> + +<ul class="card-grid"> + <li><span><a href="/en-US/docs/Web/JavaScript/Guide/Indexed_collections">Collezioni Indicizzate</a></span> + + <p><a href="/en-US/docs/Web/JavaScript/Guide/Indexed_collections#Array_object">Vettori</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Indexed_collections#Typed_Arrays">Vettori tipizzati</a></p> + </li> + <li><span><a href="/en-US/docs/Web/JavaScript/Guide/Keyed_collections">Collezioni Chiave-Valore</a></span> + <p><code><a href="/en-US/docs/Web/JavaScript/Guide/Keyed_collections#Map_object">Map</a></code><br> + <code><a href="/en-US/docs/Web/JavaScript/Guide/Keyed_collections#WeakMap_object">WeakMap</a></code><br> + <code><a href="/en-US/docs/Web/JavaScript/Guide/Keyed_collections#Set_object">Set</a></code><br> + <code><a href="/en-US/docs/Web/JavaScript/Guide/Keyed_collections#WeakSet_object">WeakSet</a></code></p> + </li> + <li><span><a href="/en-US/docs/Web/JavaScript/Guide/Working_with_Objects">Lavorare con gli Oggetti</a></span> + <p><a href="/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Objects_and_properties">Oggetti e proprietà</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Creating_new_objects">Creare Oggetti</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Defining_methods">Definire i metodi</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Defining_getters_and_setters">Getter e setter</a></p> + </li> + <li><span><a href="/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model">Dettagli sul modello a Oggetti</a></span> + <p><a href="/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model#Class-based_vs._prototype-based_languages">OOP basata su prototopi</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model#Creating_the_hierarchy">Creare una gerarchia di Oggeti</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model#Property_inheritance_revisited">Ereditarietà</a></p> + </li> +</ul> + +<ul class="card-grid"> + <li><span><a href="/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators">Iteratori & Generatori</a></span> + + <p><a href="/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#Iterators">Iteratori</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#Iterables">Iterabili</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators#Generators">Generatori</a></p> + </li> + <li><span><a href="/en-US/docs/Web/JavaScript/Guide/Meta_programming">Meta-programmazione</a></span> + <p><code><a href="/en-US/docs/Web/JavaScript/Guide/Meta_programming#Proxies">Proxy</a></code><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Meta_programming#Handlers_and_traps">Gestori e Trappole</a><br> + <a href="/en-US/docs/Web/JavaScript/Guide/Meta_programming#Revocable_Proxy">Proxy revocabile</a><br> + <code><a href="/en-US/docs/Web/JavaScript/Guide/Meta_programming#Reflection">Reflect</a></code></p> + </li> +</ul> + +<p>{{Next("Web/JavaScript/Guide/Introduction")}}</p> diff --git a/files/it/web/javascript/guida/introduzione/index.html b/files/it/web/javascript/guida/introduzione/index.html new file mode 100644 index 0000000000..3825ded91c --- /dev/null +++ b/files/it/web/javascript/guida/introduzione/index.html @@ -0,0 +1,140 @@ +--- +title: Introduzione +slug: Web/JavaScript/Guida/Introduzione +tags: + - Guida + - JavaScript +translation_of: Web/JavaScript/Guide/Introduction +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammar_and_types")}}</div> + +<p class="summary">Questo capitolo introduce JavaScript e discute alcuni dei suoi concetti fondamentali.</p> + +<h2 id="Che_cosa_dovresti_già_sapere">Che cosa dovresti già sapere</h2> + +<p>Questa guida parte dal presupposto che tu abbia già queste nozioni di base:</p> + +<ul> + <li>Una comprensione generica di Internet e del World Wide Web ({{Glossary("WWW")}}).</li> + <li>Una buona conoscenza operativa del HyperText Markup Language ({{Glossary("HTML")}}).</li> + <li>Un po' di esperienza di programmazione. Se sei nuovo della programmazione, prova uno dei tutorials linkati nella pagina principale di <a href="/en-US/docs/Web/JavaScript">JavaScript</a>.</li> +</ul> + +<h2 id="Dove_trovare_informazioni_su_JavaScript">Dove trovare informazioni su JavaScript</h2> + +<p>La documentazione JavaScript su MDN comprende:</p> + +<ul> + <li><a href="/it-IT/Learn">Capire il web</a> fornisce informazioni per i principianti ed introduce i concetti base della programmazione e di Internet.</li> + <li><a href="/en-US/docs/Web/JavaScript/Guide">Guida JavaScript</a> (questa guida) fornisce una panoramica su JavaScript ed i suoi oggetti.</li> + <li><a href="/en-US/docs/Web/JavaScript/Reference">Riferimento JavaScript</a> fornisce materiale di riferimento dettagliato su JavaScript.</li> +</ul> + +<p>Se sei nuovo di JavaScript, inizia con gli articoli presenti in <a href="/it-IT/Learn">Capire il web</a> e nella <a href="/en-US/docs/Web/JavaScript/Guide">Guida JavaScript</a>. Quando avrai una chiara comprensione dei fondamentali, potrai usare il <a href="/en-US/docs/Web/JavaScript/Reference">Riferimento JavaScript</a> per apprendere maggiori dettagli su singoli oggetti e parti del linguaggio.</p> + +<h2 id="Che_cos'è_JavaScript">Che cos'è JavaScript?</h2> + +<p>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.</p> + +<p>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:</p> + +<ul> + <li><em>Client-side JavaScript</em> estende il linguaggio base fornendo oggetti per controllare il browser ed il suo Document Object Model (DOM). Per esempio, le estensioni client-side permettono ad una applicazione di inserire elementi in un form HTML e rispondere ad eventi dell'utente come il click del mouse, input nei form e navigazione delle pagine.</li> + <li><em>Server-side JavaScript</em> estende il linguaggio base fornendo oggetti rilevanti per eseguire JavaScript in un server. Per esempio le estensioni server-side consentono ad una applicazione di comunicare con un database, forniscono continuità di informazioni da una chiamata ad un altra dell'applicazione, o permettono la manipolazione di files nel server.</li> +</ul> + +<h2 id="JavaScript_and_Java" name="JavaScript_and_Java">JavaScript e Java</h2> + +<p>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.<br> + 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.</p> + +<p>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.</p> + +<p>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.</p> + +<p>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.</p> + +<table class="standard-table"> + <caption>JavaScript confrontato con Java</caption> + <thead> + <tr> + <th scope="col">JavaScript</th> + <th scope="col">Java</th> + </tr> + </thead> + <tbody> + <tr> + <td> + <p>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.</p> + </td> + <td> + <p>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.</p> + </td> + </tr> + <tr> + <td>Le variabili ed i tipi non sono dichiarati (tipizzazione dinamica).</td> + <td>Le variabili ed i tipi di dato devono essere dichiarati (tipizzazione statica).</td> + </tr> + <tr> + <td>Non si può scrivere automaticamente suk disco fisso.</td> + <td>Si può scrivere automaticamente su disco fisso.</td> + </tr> + </tbody> +</table> + +<p>Per maggiori informazioni sulle differenze tra JavaScript e Java, vedi il capitolo <a href="/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model">Dettagli sul modello ad oggetti</a>.</p> + +<h2 id="JavaScript_and_the_ECMAScript_Specification" name="JavaScript_and_the_ECMAScript_Specification">JavaScript e le specifiche ECMAScript</h2> + +<p>JavaScript è standardizzato da <a class="external" href="http://www.ecma-international.org/">Ecma International</a> — 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 <a href="/en-US/docs/Web/JavaScript/New_in_JavaScript">Novità in JavaScript</a> per conoscere di più sulle differenti versioni di JavaScript e delle edizioni delle specifiche ECMAScript.</p> + +<p>Lo standard ECMA-262 è anche approvato da <a class="external" href="http://www.iso.ch/">ISO</a> (International Organization for Standardization) come ISO-16262. Si possono trovare le specifiche nel <a class="external" href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">sito Ecma internazionale</a>. Le specifiche ECMAScript non descrivono il Document Object Model (DOM), che viene standardizzato dal <a class="external" href="http://www.w3.org/">World Wide Web Consortium (W3C)</a>. 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 <a href="/en-US/docs/Web/JavaScript/JavaScript_technologies_overview">Panoramicha delle tecnologie JavaScript</a>.</p> + +<h3 id="JavaScript_Documentation_versus_the_ECMAScript_Specification" name="JavaScript_Documentation_versus_the_ECMAScript_Specification">Documentazione JavaScript a confronto con le specifiche ECMAScript</h3> + +<p>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).</p> + +<p>La documentazione ECMAScript non è indirizzata ad aiutare i programmatori di script; usa la documentazione di JavaScript per informazioni su come scrivere script.</p> + +<p>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.</p> + +<p>La documentazione JavaScript descrive aspetti del linguaggio che sono appropriati per il programmatore JavaScript.</p> + +<h2 id="Iniziare_con_JavaScript">Iniziare con JavaScript</h2> + +<p>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.</p> + +<p>In Firefox sono presenti due strumenti che sono utili per sperimentare con JavaScript: la Console Web ed il Blocco per gli appunti.</p> + +<h3 id="La_Console_Web">La Console Web</h3> + +<p>La <a href="/en-US/docs/Tools/Web_Console">Console Web</a> espone informazioni sulla pagina Web attualmente caricata, ed include una <a href="/en-US/docs/Tools/Web_Console#The_command_line_interpreter">command line</a> che si può usare per eseguire espressioni nella pagina corrente.</p> + +<p>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:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/7363/web-console-commandline.png" style="display: block; margin-left: auto; margin-right: auto;"></p> + +<h3 id="Blocco_per_gli_appunti">Blocco per gli appunti</h3> + +<p>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 <a href="/en-US/docs/Tools/Scratchpad">Blocco per gli appunti</a> è uno strumento migliore.</p> + +<p>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.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/7365/scratchpad.png" style="display: block; margin-left: auto; margin-right: auto;"></p> + +<h3 id="Hello_world">Hello world</h3> + +<p>Per iniziare a scrivere programmi JavaScript, apri il Blocco per gli appunti e scrivi il tuo primo codice "Hello world" JavaScript:</p> + +<pre class="brush: js">function greetMe(yourName) { + alert("Hello " + yourName); +} + +greetMe("World"); +</pre> + +<p>Seleziona il codice nel blocco e premi Ctrl+R per vedere il risultato nel browser!</p> + +<p>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.</p> + +<p>{{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammar_and_types")}}</p> diff --git a/files/it/web/javascript/guida/iteratori_e_generatori/index.html b/files/it/web/javascript/guida/iteratori_e_generatori/index.html new file mode 100644 index 0000000000..49b220cdd1 --- /dev/null +++ b/files/it/web/javascript/guida/iteratori_e_generatori/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 +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Meta_programming")}}</div> + +<p class="summary">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")}}.</p> + +<p>Per maggiori dettagli, vedi anche:</p> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Iteration_protocols">Iteration protocols</a></li> + <li>{{jsxref("Statements/for...of","for...of")}}</li> + <li>{{jsxref("Statements/function*","function*")}} e {{jsxref("Generator")}}</li> + <li>{{jsxref("Operators/yield","yield")}} e {{jsxref("Operators/yield*","yield*")}}</li> +</ul> + +<h2 id="Iterators">Iterators</h2> + +<p>Un oggetto è un <strong>iterator</strong> 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 <code>next()</code> , il quale ritorna l'elemento successivo della sequenza. Questo metodo ritorna un oggetto con due proprietà: <code>done</code> e<code>value</code>.</p> + +<p>Una volta che è stato creato, un iterator può essere utlizzato esplicitamente chiamando più volte il metodo <code>next()</code>.</p> + +<pre class="brush: js">function makeIterator(array) { + var nextIndex = 0; + + return { + next: function() { + return nextIndex < array.length ? + {value: array[nextIndex++], done: false} : + {done: true}; + } + }; +}</pre> + +<p>Una volta che un iterator è stato inizializzato, il metodo<code>next()</code> può essere chiamato per accedere a coppie chiave-valore dall'oggetto ritornato:</p> + +<pre class="brush: js">var it = makeIterator(['yo', 'ya']); +console.log(it.next().value); // 'yo' +console.log(it.next().value); // 'ya' +console.log(it.next().done); // true</pre> + +<h2 id="Generators">Generators</h2> + +<p>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 <strong>{{jsxref("Global_Objects/Generator","Generators","","true")}}</strong> forniscono una potente alternativa: ti permettono di definire un algoritmo iterativo scrivendo una singola funzione in grado di mantenere il proprio stato.</p> + +<p>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*")}}.</p> + +<pre class="brush: js">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 +// ...</pre> + +<h2 id="Iterables">Iterables</h2> + +<p>Un oggetto è un <strong>iterable</strong> 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.</p> + +<p>Affinché un oggetto possa essere considerato un <strong>iterable</strong> deve implementare il metodo <strong>@@iterator</strong>, cioè l'oggetto (o uno degli oggetti che lo precedono nella <a href="/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain">catena dei prototipi</a>) deve avere una proprietà con una chiave {{jsxref("Symbol.iterator")}}.</p> + +<h3 id="Iterables_definiti_dall'utente">Iterables definiti dall'utente</h3> + +<p>Possiamo creare i nostri iterables in questo modo:</p> + +<pre class="brush: js">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] +</pre> + +<h3 id="Iterables_Built-in">Iterables Built-in</h3> + +<p>{{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")}}.</p> + +<h3 id="Sintassi_che_si_aspettano_degli_iterables">Sintassi che si aspettano degli iterables</h3> + +<p>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")}}.</p> + +<pre class="brush: js">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" + +</pre> + +<h2 id="Generators_avanzati">Generators avanzati</h2> + +<p>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 <code>idMaker()</code>.</p> + +<p>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 <code>next()</code> sarà trattato come il risultato dell'ultima espressione <code>yield</code> che ha messo in pausa il generator.</p> + +<p>Ecco un generator che produce una sequenza di numeri di Fibonacci. In questo generator il metodo<code>next(x)</code> può essere utilizzato per reinizializzare la sequenza:</p> + +<pre class="brush: js">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</pre> + +<p>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 <code>yield</code> che è attualmente sospeso fosse invece una dichiarazione <code>throw <em>value</em></code>.</p> + +<p>Se non si incontra uno <code>yield</code> durante la risoluzione della eccezione lanciata, allora l'eccezione si propagherà fino alla chiamata a<code>throw()</code>, e in tutte le successive chiamate a <code>next()</code> la proprietà <code>done</code> sarà<code>true</code>.</p> + +<p>I generators hanno un metodo {{jsxref("Global_Objects/Generator/return","return(value)")}} che ritorna un valore e termina il generator stesso.</p> + +<p>{{PreviousNext("Web/JavaScript/Guide/Details_of_the_Object_Model", "Web/JavaScript/Guide/Meta_programming")}}</p> diff --git a/files/it/web/javascript/guida/loops_and_iteration/index.html b/files/it/web/javascript/guida/loops_and_iteration/index.html new file mode 100644 index 0000000000..c677151181 --- /dev/null +++ b/files/it/web/javascript/guida/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 +--- +<div>{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}</div> + +<p class="summary">I cicli offrono un modo semplice e rapido per fare cose ripetutamente. Questo capitolo della <a href="/en-US/docs/Web/JavaScript/Guide">guida al JavaScript</a> introduce i diversi metodi di iterazione disponibili in JavaScript.</p> + +<p>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:</p> + +<pre class="brush: js notranslate">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'); +} +</pre> + +<p>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).</p> + +<p>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.</p> + +<p>Le istruzioni per i loop foriti in JavaScript sono:</p> + +<ul> + <li>{{anch("ciclo for")}}</li> + <li>{{anch("ciclo do...while")}}</li> + <li>{{anch("ciclo while")}}</li> + <li>{{anch("labeled statement")}}</li> + <li>{{anch("break statement")}}</li> + <li>{{anch("continue statement")}}</li> + <li>{{anch("ciclo for...in")}}</li> + <li>{{anch("ciclo for...of")}}</li> +</ul> + +<h2 id="Istruzione_for">Istruzione <code>for</code></h2> + +<p>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 <code>for</code> è definita come segue:</p> + +<pre class="syntaxbox notranslate">for ([espressioneIniziale]; [condizione]; [incremento]) + istruzione +</pre> + +<p>Quando viene eseguito un ciclo <code>for</code>, questo è ciò che accade:</p> + +<ol> + <li><code>espressioneIniziale</code>, 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.</li> + <li>La <code>condizione</code> viene verificata. Se il suo valore è true, l'espressione <code>istruzione</code> viene eseguita. Se invece <code>condizione</code> è false, il ciclo finisce. Se <code>condizione</code> è omessa, l'espressione si assume sia true.</li> + <li><code>istruzione</code> viene esguita. Per eseguire diverse istruzioni, è necessario usare il blocco (<code>{ ... }</code>) per raggrupparle.</li> + <li>Viene incrementata la l'espressione <code>incremento</code>, se esiste, eseguita, e il ciclo <code>for</code> va al passo successivo.</li> +</ol> + +<h3 id="Esempio"><strong>Esempio</strong></h3> + +<p>Il seguente esempio contiene un ciclo <code>for</code> che conta il numero di opzioni selezionate in una lista a scorrimento (a {{HTMLElement("select")}} che permette selezioni multiple). L'istruzione <code>for</code> dichiara una variabile <code>i</code> e la inizializza a zero. Controlla che <code>i</code> sia minore del numero di opzioni dell'elemento <code><select></code> , esegue l'istruzione <code>if</code> e incrementa <code>i</code> di uno alla fine di ogni ciclo.</p> + +<pre class="brush: html notranslate"><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> + +</pre> + +<h2 id="Istruzione_do...while">Istruzione<code> do...while</code></h2> + +<p>Il ciclo {{jsxref("statements/do...while", "do...while")}} si ripete finché la <code>condizione</code> non è falsa. Il <code>do...while</code> è viene definito come segue:</p> + +<pre class="syntaxbox notranslate">do + istruzione +while (condizione); +</pre> + +<p>l'<code>istruzione</code> viene eseguita una volta prima che la <code>condizione</code> venga controllata. Per eseguire più istruzioni, è necessario usare il blocco (<code>{ ... }</code>) . Se la <code>condizione</code> è vera l'<code>istruzione</code> viene eseguita nuovamente. Alla fine di ogni esecuzione di <code>istruzione</code>, <code>condizione</code> viene controllata. Quando <code>condizione</code> è falsa l'esecuzione del ciclo <code>do..while</code> termina.</p> + +<h3 id="Esempio_2"><strong>Esempio</strong></h3> + +<p>Nel seguente esempio il ciclo do..while itera almeno una volta e continua finché il valore di <code>i</code> è minore di 5.</p> + +<pre class="brush: js notranslate">var i = 0; +do { + i += 1; + console.log(i); +} while (i < 5);</pre> + +<h2 id="Istruzione_while">Istruzione <code>while</code></h2> + +<p><code><font face="Open Sans, arial, sans-serif">Il ciclo</font> </code>{{jsxref("statements/while","while")}} esegue un'<code>istruzione</code> fino a quando una <code>condizione</code> è true. Ecco un esempio si un ciclo <code>while</code>:</p> + +<pre class="syntaxbox notranslate">while (condizione) + istruzione //...statement +</pre> + +<p>Se <code>condizione</code> diventa false, <code>istruzione</code> non viene eseguita a si passa ad eseguire i comandi successivi.</p> + +<p>Durante il ciclo c<code>ondizione</code> viene testata prima di eseguire <code>istruzione</code>. Se c<code>ondizione </code>è true, <code>istruzione</code> viene esguita e c<code>ondizione</code> viene verificata nuovamente. Se <code>condizione</code> è false il ciclo di ferma e viene eseguito il codice successivo al ciclo <code>while</code>.</p> + +<p>Per eseguire istruzioni multiple, è necessario usare il blocco ({ ... }) così da raggruppare le istruzioni.</p> + +<h3 id="Esempio_1"><strong>Esempio 1</strong></h3> + +<p>Il seguente esempio di ciclo <code>while</code> si ripete fino a quando <code>n</code> è minore di tre:</p> + +<pre class="brush: js notranslate">var n = 0; +var x = 0; +while (n < 3) { + n++; + x += n; +} +</pre> + +<p>Ad ogni iterazione, il ciclo incrementa n e aggiunge quel valore a x. Pertanto,<code>x</code> e <code>n</code> assumono i seguenti valori:</p> + +<ul> + <li>Dopo il primo passaggio: <code>n</code> = 1 and <code>x</code> = 1</li> + <li>Dopo il secondo passaggio: <code>n</code> = 2 and <code>x</code> = 3</li> + <li>Dopo il terzo passaggio: <code>n</code> = 3 and <code>x</code> = 6</li> +</ul> + +<p>Dopo aver completato il terzo passaggio, la condizione <code>n < 3</code> non è più vera, quindi il ciclo termina.</p> + +<h3 id="Esempio_2_2"><strong>Esempio 2</strong></h3> + +<p>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 <code>while</code> vengono eseguite per sempre perché la condizione non diventa mai falsa:</p> + +<div class="blockIndicator warning"> +<pre class="brush: js notranslate">//I loop infiniti non vanno affatto bene +while (true) { + console.log("Buongiorno, Mondo"); +}</pre> +</div> + +<h2 id="Istruzione_etichettata">Istruzione "etichettata"</h2> + +<p>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 <code>break</code> o <code>continue</code> per indicare se un programma deve interrompere il loop o continuare la sua esecuzione.</p> + +<p>La sintassi dell'istruzione etichettata è simile alla seguente:</p> + +<pre class="syntaxbox notranslate">label : + istruzione // statement +</pre> + +<p>Il valore dell'etichetta <code><em>label </em></code>può essere qualsiasi identificatore JavaScript che non sia una parola riservata. L'affermazione che ti identifichi con un'etichetta <code><em>statement</em></code> può essere una qualsiasi affermazione.</p> + +<h3 id="Esempio_3"><strong>Esempio</strong></h3> + +<p>In questo esempio, la label <code>markLoop</code> identifica un ciclo <code>while</code>.</p> + +<pre class="brush: js notranslate">markLoop: +while (theMark == true) { + doSomething(); +}</pre> + +<h2 id="Istruzione_break">Istruzione <code>break</code></h2> + +<p>Utilizzare l'istruzione {{jsxref("statements/break","break")}} per terminare un ciclo, uno <code>switch</code> o in congiunzione con un'istruzione etichettata.</p> + +<ul> + <li>Quando si utilizza <code>break</code> senza un'etichetta, termina l'enclosure più interno <code>while</code>, <code>do-while</code>, <code>for</code>, o <code>switch</code> immediatamente e trasferisce il controllo alla seguente istruzione.</li> + <li>Quando usi la <code>break</code> con un'etichetta, termina l'istruzione etichettata specificata.</li> +</ul> + +<p>La sintassi dell'istruzione <code>break</code> è simile a questa:</p> + +<pre class="syntaxbox notranslate">break [<em>label</em>]; +</pre> + +<p>La prima forma della sintassi termina il ciclo <code>switch</code> di chiusura più interno; la seconda forma della sintassi termina l'istruzione dell'etichettata specificata.</p> + +<h3 id="Esempio_1_2"><strong>Esempio</strong> <strong>1</strong></h3> + +<p>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 è <code>theValue</code>:</p> + +<pre class="brush: js notranslate">for (var i = 0; i < a.length; i++) { + if (a[i] == theValue) { + break; + } +}</pre> + +<h3 id="Esempio_2_Breaking_to_a_label_-_Interruzione_su_unetichetta"><strong>Esempio 2: </strong>Breaking to a label - Interruzione su un'etichetta</h3> + +<pre class="brush: js notranslate">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; + } + } +}</pre> + +<h2 id="Istruzione_continue">Istruzione <code>continue</code></h2> + +<p>The {{jsxref("statements/continue","continue")}} statement can be used to restart a <code>while</code>, <code>do-while</code>, <code>for</code>, or <code>label</code> statement.</p> + +<ul> + <li>Quando usi <code>continue</code> senza un'etichetta, termina l'iterazione corrente dell'istruzione racchiudente, mentre <code>while</code>, <code>do-while</code>, o <code>for</code> continua l'esecuzione del ciclo con l'iterazione successiva. In contrasto con l'istruzione <code>break</code>, <code>continue</code> non termina interamente l'esecuzione del ciclo. In un ciclo <code>while</code>, torna alla condizione. In un ciclo <code>for</code>, salta all'espressione di incremento <code>increment-expression</code>.</li> + <li>Quando si utilizza <code>continue</code> con un'etichetta, si applica all'istruzione looping identificata con tale etichetta.</li> +</ul> + +<p>La sintassi dell'istruzione <code>continue</code> ha il seguente aspetto:</p> + +<pre class="syntaxbox notranslate"><code>continue</code> [<em>label</em>]; +</pre> + +<h3 id="Esempio_1_3"><strong>Esempio 1</strong></h3> + +<p>L'esempio seguente mostra un ciclo <code>while</code> con un'istruzione <code>continue</code> che viene eseguita quando il valore di <code>i</code> è tre. Quindi, <code>n</code> assume i valori uno, tre, sette e dodici.</p> + +<pre class="brush: js notranslate">var i = 0; +var n = 0; +while (i < 5) { + i++; + if (i == 3) { + continue; + } + n += i; +}</pre> + +<h3 id="Esempio_2_3"><strong>Esempio 2</strong></h3> + +<p>Una dichiarazione etichettata <em><code>checkiandj</code> </em>contiene una dichiarazione etichettata <em><code>checkj</code></em>. Se si incontra <code>continue</code> il programma termina l'iterazione corrente di <em><code>checkj</code></em> e inizia la successiva iterazione. Ogni volta che si incontra <code>continue</code>, <em><code>checkj</code></em> viene reiterato finché la condizione non restituisce <code>false</code>. Quando viene restituito <code>false</code>, il resto dell'istruzione <em><code>checkiandj</code></em> è completato e <em><code>checkiandj</code></em> reiterate fino a quando la condizione non restituisce <code>false</code>. Quando viene restituito <code>false</code>, il programma continua con la seguente istruzione <em><code>checkiandj</code></em>.</p> + +<p>Se <code>continue</code> ha un'etichetta di <em><code>checkiandj</code></em>, il programma continuerà nella parte superiore del <em><code>checkiandj</code></em> istruzione.</p> + +<pre class="brush: js notranslate">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); +}</pre> + +<h2 id="Istruzione_for...in">Istruzione <code>for...in</code></h2> + +<p>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 <code>for...in</code> ha il seguente aspetto:</p> + +<pre class="syntaxbox notranslate">for (variabile in oggetto) { + istruzione +} +// for (variable in object) { +// statements +// } +</pre> + +<h3 id="Esempio_4"><strong>Esempio</strong></h3> + +<p>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.</p> + +<pre class="brush: js notranslate">function dump_props(obj, obj_name) { + var result = ""; + for (var i in obj) { + result += obj_name + "." + i + " = " + obj[i] + "<br>"; + } + result += "<hr>"; + return result; +} +</pre> + +<p>Per un oggetto <code>car</code> con proprietà <code>make</code> e <code>model</code>, <code>result</code> sarebbe:</p> + +<pre class="brush: js notranslate">car.make = Ford +car.model = Mustang +</pre> + +<h3 id="Arrays_Matrici"><strong>Arrays / Matrici</strong></h3> + +<p>Anche se può essere allettante usarla come un modo per iterare sugli elementi {{jsxref("Array")}} , l'istruzione the <strong>for...in</strong> 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 <strong>for...in</strong> 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).</p> + +<h2 id="Istruzione_for...of">Istruzione <code>for...of</code></h2> + +<p>L'istruzione {{jsxref("statements/for...of","for...of")}} crea un ciclo che itera su <a href="/en-US/docs/Web/JavaScript/Guide/iterable">oggetti iterabili</a> (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.</p> + +<pre class="syntaxbox notranslate">for (<em>variabile</em> di <em>oggetto</em>) { + <em>istruzione +</em>}</pre> + +<p>Il seguente esempio mostra la differenza tra un ciclo <code>for...of</code> e un {{jsxref("statements/for...in","for...in")}} ciclo continuo. Mentre <code>for...in</code> itera sopra i nomi delle proprietà, <code>for...of</code> itera sui valori delle proprietà:</p> + +<pre class="brush:js notranslate">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" +}</pre> + +<p>{{PreviousNext("Web/JavaScript/Guide/Control_flow_and_error_handling", "Web/JavaScript/Guide/Functions")}}</p> |