diff options
Diffstat (limited to 'files/it/web/javascript/reference/functions/arrow_functions/index.html')
-rw-r--r-- | files/it/web/javascript/reference/functions/arrow_functions/index.html | 394 |
1 files changed, 394 insertions, 0 deletions
diff --git a/files/it/web/javascript/reference/functions/arrow_functions/index.html b/files/it/web/javascript/reference/functions/arrow_functions/index.html new file mode 100644 index 0000000000..2dd258966d --- /dev/null +++ b/files/it/web/javascript/reference/functions/arrow_functions/index.html @@ -0,0 +1,394 @@ +--- +title: Funzioni a freccia +slug: Web/JavaScript/Reference/Functions_and_function_scope/Arrow_functions +tags: + - ECMAScript6 + - Funzioni + - Intermediate + - JavaScript + - Reference +translation_of: Web/JavaScript/Reference/Functions/Arrow_functions +--- +<div>{{jsSidebar("Functions")}}</div> + +<p>Una <strong>funzione a freccia </strong>ha una sintassi più compatta rispetto alla <a href="/it/docs/Web/JavaScript/Reference/Operators/function">notazione a funzione</a> e non associa i propri <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/this">this</a></code>, <a href="/en-US/docs/Web/JavaScript/Reference/Functions/arguments">arguments</a>, <a href="/en-US/docs/Web/JavaScript/Reference/Operators/super">super</a> o <a href="/en-US/docs/Web/JavaScript/Reference/Operators/new.target">new.target</a>. Le funzioni a freccia sono sempre <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name">anonime</a>. Questa notazione è maggiormente indicata per le funzioni che non sono metodi, e non possono essere usate come costruttori.</p> + +<h2 id="Sintassi">Sintassi</h2> + +<h3 id="Sintassi_di_base">Sintassi di base</h3> + +<pre class="syntaxbox"><strong>(</strong><em>param1</em>, <em>param2</em>, …, <em>paramN</em><strong>) => {</strong> <em>statements</em> <strong>}</strong> +<strong>(</strong><em>param1</em>, <em>param2</em>, …, <em>paramN</em><strong>) =></strong> <em>expression</em> +// equivalente a: <strong>(</strong><em>param1</em>, <em>param2</em>, …, <em>paramN</em><strong>)</strong> => { return <em>expression</em>; } + +// Le Parentesi sono opzionali se è presente un solo parametro: +<em>(singleParam)</em> <strong>=> {</strong> <em>statements</em> <strong>}</strong> +<em>singleParam</em> <strong>=></strong> { <em>statements }</em> + +// Una funzione senza parametri richiede comunque le parentesi: +<strong>() => {</strong> <em>statements</em> <strong>} +</strong>() => <em>expression</em> // equivalente a: () => { return <em>expression</em>; } +</pre> + +<h3 id="Sintassi_avanzata">Sintassi avanzata</h3> + +<pre class="syntaxbox">// Il body tra parentesi indica la restituzione di un oggetto: +<em>params</em> => ({<em>foo: bar</em>}) + +// Sono supportati <a href="/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters">...rest</a> e <a href="/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters">i parametri di default</a> +(<em>param1</em>, <em>param2</em>, <strong>...rest</strong>) => { <em>statements</em> } +(<em>param1</em> <strong>= defaultValue1</strong>, <em>param2</em>, …, paramN <strong>= defaultValueN</strong>) => { <em>statements</em> } + +// Si può anche <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">destrutturare</a> all'interno della lista dei parametri +var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c; +f(); // 6 +</pre> + +<p>Esempi dettagliati di sintassi sono disponibili <a href="http://wiki.ecmascript.org/doku.php?id=harmony:arrow_function_syntax">qui</a>.</p> + +<h2 id="Descrizione">Descrizione</h2> + +<p>Vedi anche <a href="https://hacks.mozilla.org/2015/06/es6-in-depth-arrow-functions/">"ES6 In Depth: Arrow functions" su hacks.mozilla.org</a>.</p> + +<p>L'introduzione delle funzioni a freccia è stata influenzata da due fattori: sintassi più compatta e la non associazione di <code>this</code>.</p> + +<h3 id="Funzioni_più_corte">Funzioni più corte</h3> + +<p>In alcuni pattern, è meglio avere funzioni più corte. Per comparazione:</p> + +<pre class="brush: js">var materials = [ + "Hydrogen", + "Helium", + "Lithium", + "Beryllium" +]; + +materials.map(function(material) { + return material.length; +}); <code>// [8, 6, 7, 9] +</code> +materials.map((material) => { +<code> return material.length; +}); // [8, 6, 7, 9] +</code> +<code>materials.map(material => material.length); // [8, 6, 7, 9]</code></pre> + +<h3 id="Mancato_binding_di_this">Mancato binding di <code>this</code></h3> + +<p>Prima delle funzioni a freccia, ogni nuova funzione definiva il proprio <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/this">this</a></code> (un nuovo oggetto nel caso di un costruttore, undefined se una funzione viene chiamata in <a href="/en-US/docs/Web/JavaScript/Reference/Strict_mode">strict mode</a>, l'oggetto di contesto se la funzione viene chiamata come "metodo", etc.). Questo è risultato fastidioso in uno stile di programmazione orientato agli oggetti.</p> + +<pre class="brush: js">function Person() { + // The Person() constructor defines `this` as an instance of itself. + this.age = 0; + + setInterval(function growUp() { + // In non-strict mode, the growUp() function defines `this` + // as the global object, which is different from the `this` + // defined by the Person() constructor. + this.age++; + }, 1000); +} + +var p = new Person();</pre> + +<p>In ECMAScript 3/5, questo problema veniva aggirato assegnando il valore this a una variabile.</p> + +<pre class="brush: js">function Person() { + var that = this; + that.age = 0; + + setInterval(function growUp() { + // The callback refers to the `that` variable of which + // the value is the expected object. + that.age++; + }, 1000); +}</pre> + +<p>In alternativa, poteva essere usato <a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind">Function.prototype.bind</a> per assegnare il valore corretto di this da usare nella funzione <code>growUp()</code>.</p> + +<p>Una funziona a freccia invece non crea il proprio <code>this</code>, e quindi <code>this</code> mantiene il significato che aveva all'interno dello scope genitore. Perciò il codice seguente funziona come ci si aspetta.</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> + +<h4 id="Relazione_con_strict_mode">Relazione con strict mode</h4> + +<p>Poiché <code>this</code> è lessicale, le regole di <a href="/en-US/docs/Web/JavaScript/Reference/Strict_mode">strict mode</a> relative a <code>this</code> sono semplicemente ignorate.</p> + +<pre class="brush: js">var f = () => {'use strict'; return this}; +f() === window; // o l'oggetto globale</pre> + +<p>Il resto delle regole si applica normalmente.</p> + +<h4 id="Invocazione_attraverso_call_or_apply">Invocazione attraverso call or apply</h4> + +<p>Poiché <code>this</code><em> </em>non viene assegnato nelle funzioni a freccia, i metodi <code>call()</code><em> </em>o <code>apply()</code> possono passare solo come argomenti; <code>this</code> viene ignorato:</p> + +<pre class="brush: js">var adder = { + base : 1, + + add : function(a) { + var f = v => v + this.base; + return f(a); + }, + + addThruCall: function(a) { + var f = v => v + this.base; + var b = { + base : 2 + }; + + return f.call(b, a); + } +}; + +console.log(adder.add(1)); // This would log to 2 +console.log(adder.addThruCall(1)); // This would log to 2 still</pre> + +<h3 id="Mancato_binding_di_arguments">Mancato binding di <code>arguments</code></h3> + +<p>Le funzioni a freccia non definiscono il proprio <code><a href="/en-US/docs/Web/JavaScript/Reference/Functions/arguments">arguments</a>. </code>Perciò, <code>arguments</code> è semplicemente una reference alla variabile nello scope genitore.</p> + +<pre class="brush: js">var arguments = 42; +var arr = () => arguments; + +arr(); // 42 + +function foo() { + var f = (i) => arguments[0]+i; // <em>foo</em>'s implicit arguments binding + return f(2); +} + +foo(1); // 3</pre> + +<p>Le funzioni a freccia non hanno il proprio oggetto <code>arguments</code>, ma in molti casi i parametri <a href="/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters">rest</a> rappresentano una valida alternativa:</p> + +<pre class="brush: js">function foo() { + var f = (...args) => args[0]; + return f(2); +} + +foo(1); // 2</pre> + +<h3 id="Funzioni_a_freccia_come_metodi">Funzioni a freccia come metodi</h3> + +<p>Come già citato, le funzioni a freccia sono sconsigliate come metodi. Vediamo cosa succede quando proviamo a usarle: </p> + +<pre class="brush: js">'use strict'; +var obj = { + i: 10, + b: () => console.log(this.i, this), + c: function() { + console.log( this.i, this) + } +} +obj.b(); // prints undefined, Window +obj.c(); // prints 10, Object {...}</pre> + +<p>Le funzioni a freccia non definiscono ("bind") il proprio <code>this</code>. un altro esempio usando {{jsxref("Object.defineProperty()")}}:</p> + +<pre class="brush: js">'use strict'; +var obj = { + a: 10 +}; + +Object.defineProperty(obj, "b", { + get: () => { + console.log(this.a, typeof this.a, this); + return this.a+10; // represents global object 'Window', therefore 'this.a' returns 'undefined' + } +}); +</pre> + +<h3 id="Uso_dell'operatore_new">Uso dell'operatore <code>new</code> </h3> + +<p>Le funzioni a freccia non possono essere usate come costruttori, ed emetteranno un errore se usate con <code>new</code>.</p> + +<h3 id="Uso_di_yield">Uso di <code>yield</code> </h3> + +<p>La keyword <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/yield">yield</a></code> non deve essere usata nel body di una funzione a freccia (eccetto quando permesso in eventuali funzioni al loro interno). Conseguentemente, le funzioni a freccia non possono essere usate come generatori.</p> + +<h2 id="Body_della_funzione">Body della funzione</h2> + +<p>Le funzioni a freccia possono avere un "body conciso" o l'usuale "blocco body".</p> + +<p>Nel primo caso è necessaria solo un'espressione, e il return è implicito. Nel secondo caso, devi usare esplicitamente <code>return</code>.</p> + +<pre class="brush: js">var func = x => x * x; // concise syntax, implied "return" +var func = (x, y) => { return x + y; }; // with block body, explicit "return" needed +</pre> + +<h2 id="Restituire_object_literals">Restituire object literals</h2> + +<p>Tieni a mente che restituire oggetti letterali usando la sintassi concisa <code>params => {object:literal}</code> non funzionerà:</p> + +<pre class="brush: js">var func = () => { foo: 1 }; // Calling func() returns undefined! +var func = () => { foo: function() {} }; // SyntaxError: function statement requires a name</pre> + +<p>Questo perché il codice all'interno delle parentesi graffe ({}) è processato come una sequenza di statement (i.e. <code>foo</code> è trattato come un label, non come una key di un oggetto).</p> + +<p>Tuttavia, è sufficente racchiudere l'oggetto tra parentesi tonde:</p> + +<pre class="brush: js">var func = () => ({ foo: 1 });</pre> + +<h2 id="Newline">Newline</h2> + +<p>Le funzioni a freccia non possono contenere un newline tra i parametri e la freccia.</p> + +<pre class="brush: js">var func = () + => 1; // SyntaxError: expected expression, got '=>'</pre> + +<h2 id="Ordine_di_parsing">Ordine di parsing</h2> + +<p>La freccia in una funziona a freccia non è un'operatore, ma le funzioni a freccia hanno delle regole di parsing specifiche che interagiscono differentemente con <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence">la precedenza degli operatori</a>, rispetto alle funzioni normali.</p> + +<pre class="brush: js">let callback; + +callback = callback || function() {}; // ok +callback = callback || () => {}; // SyntaxError: invalid arrow-function arguments +callback = callback || (() => {}); // ok +</pre> + +<h2 id="Altri_esempi">Altri esempi</h2> + +<pre class="brush: js">// Una funzione a freccie vuota restituisce undefined +let empty = () => {}; + +(() => "foobar")() // <a href="/en-US/docs/Glossary/IIFE">IIFE</a>, restituisce "foobar" + +var simple = a => a > 15 ? 15 : a; +simple(16); // 15 +simple(10); // 10 + +let max = (a, b) => a > b ? a : b; + +// Più semplice gestire filtering, mapping, ... di array + +var arr = [5, 6, 13, 0, 1, 18, 23]; +var sum = arr.reduce((a, b) => a + b); // 66 +var even = arr.filter(v => v % 2 == 0); // [6, 0, 18] +var double = arr.map(v => v * 2); // [10, 12, 26, 0, 2, 36, 46] + +// Le catene di promise sono più concise +promise.then(a => { + // ... +}).then(b => { + // ... +}); + +// le funzioni a freccia senza parametri sono più semplici da visualizzare +setTimeout( _ => { + console.log("I happen sooner"); + setTimeout( _ => { + // deeper code + console.log("I happen later"); + }, 1); +}, 1); +</pre> + +<p> </p> + +<p> </p> + +<p> </p> + +<h2 id="Specifiche">Specifiche</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>Initial definition.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="Compatibilità_dei_Browser">Compatibilità dei Browser </h2> + +<div>{{CompatibilityTable}}</div> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Edge</th> + <th>IE</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatChrome(45.0)}}</td> + <td>{{CompatGeckoDesktop("22.0")}}</td> + <td>{{CompatVersionUnknown}}</td> + <td> + <p>{{CompatNo}}</p> + </td> + <td>{{CompatOpera(32)}}</td> + <td>{{CompatSafari(10.0)}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Android Webview</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + <th>Chrome for Android</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatNo}}</td> + <td>{{CompatChrome(45.0)}}</td> + <td>{{CompatGeckoMobile("22.0")}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatSafari(10.0)}}</td> + <td>{{CompatChrome(45.0)}}</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="Note_specifiche_per_Firefox">Note specifiche per Firefox</h2> + +<ul> + <li>L'implementazione iniziale delle funzioni a freccia in Firefox le rendeva automaticamente strict. Questo è cambiato da <a href="/en-US/docs/Mozilla/Firefox/Releases/24">Firefox 24</a>. L'uso di <code>"use strict";</code> è ora obbligatorio.</li> + <li>Le funzioni a freccia sono semanticamente differenti dalle non-standard {{jsxref("Operators/Expression_Closures", "expression closures", "", 1)}} aggiunte in <a href="/en-US/Firefox/Releases/3">Firefox 3</a> (details: <a href="/en-US/docs/Web/JavaScript/New_in_JavaScript/1.8">JavaScript 1.8</a>), perché {{jsxref("Operators/Expression_Closures", "expression closures", "", 1)}} non assegnano <code>this</code> in modo lessicale.</li> + <li>Fino a <a href="/en-US/Firefox/Releases/39">Firefox 39</a>, un newline (<code>\n</code>) era erroneamente accettato dopo i parametri della funzione. Questo è stato risolto in conformità alle specifiche ES6 e codice come <code>() \n => {}</code> emetterà un {{jsxref("SyntaxError")}} in questa versione e successive.</li> +</ul> + +<h2 id="Vedi_anche">Vedi anche</h2> + +<ul> + <li><a href="https://hacks.mozilla.org/2015/06/es6-in-depth-arrow-functions/">"ES6 In Depth: Arrow functions" on hacks.mozilla.org</a></li> +</ul> |