aboutsummaryrefslogtreecommitdiff
path: root/files/it/web/javascript/reference/functions/arrow_functions/index.html
blob: eef7570ec008fbae731bc1ca9f0e13cae679c267 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
---
title: Funzioni a freccia
slug: Web/JavaScript/Reference/Functions/Arrow_functions
tags:
  - ECMAScript6
  - Funzioni
  - Intermediate
  - JavaScript
  - Reference
translation_of: Web/JavaScript/Reference/Functions/Arrow_functions
original_slug: Web/JavaScript/Reference/Functions_and_function_scope/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>) =&gt; {</strong> <em>statements</em> <strong>}</strong>
<strong>(</strong><em>param1</em>, <em>param2</em>, …, <em>paramN</em><strong>) =&gt;</strong> <em>expression</em>
// equivalente a: <strong>(</strong><em>param1</em>, <em>param2</em>, …, <em>paramN</em><strong>)</strong> =&gt; { return <em>expression</em>; }

// Le Parentesi sono opzionali se è presente un solo parametro:
<em>(singleParam)</em> <strong>=&gt; {</strong> <em>statements</em> <strong>}</strong>
<em>singleParam</em> <strong>=&gt;</strong> { <em>statements }</em>

// Una funzione senza parametri richiede comunque le parentesi:
<strong>() =&gt; {</strong> <em>statements</em> <strong>}
</strong>() =&gt; <em>expression</em> // equivalente a: () =&gt; { 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> =&gt; ({<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>) =&gt; { <em>statements</em> }
(<em>param1</em> <strong>= defaultValue1</strong>, <em>param2</em>, …, paramN <strong>= defaultValueN</strong>) =&gt; { <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}) =&gt; 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) =&gt; {
<code>  return material.length;
}); // [8, 6, 7, 9]
</code>
<code>materials.map(material =&gt; 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(() =&gt; {
    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 = () =&gt; {'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 =&gt; v + this.base;
    return f(a);
  },

  addThruCall: function(a) {
    var f = v =&gt; 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 = () =&gt; arguments;

arr(); // 42

function foo() {
  var f = (i) =&gt; 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) =&gt; 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: () =&gt; 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: () =&gt; {
    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 =&gt; x * x;                  // concise syntax, implied "return"
var func = (x, y) =&gt; { 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 =&gt; {object:literal}</code> non funzionerà:</p>

<pre class="brush: js">var func = () =&gt; {  foo: 1  };               // Calling func() returns undefined!
var func = () =&gt; {  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 = () =&gt; ({ 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 = ()
           =&gt; 1; // SyntaxError: expected expression, got '=&gt;'</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 || () =&gt; {};      // SyntaxError: invalid arrow-function arguments
callback = callback || (() =&gt; {});    // ok
</pre>

<h2 id="Altri_esempi">Altri esempi</h2>

<pre class="brush: js">// Una funzione a freccie vuota restituisce undefined
let empty = () =&gt; {};

(() =&gt; "foobar")() // <a href="/en-US/docs/Glossary/IIFE">IIFE</a>, restituisce "foobar"

var simple = a =&gt; a &gt; 15 ? 15 : a;
simple(16); // 15
simple(10); // 10

let max = (a, b) =&gt; a &gt; 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) =&gt; a + b);  // 66
var even = arr.filter(v =&gt; v % 2 == 0); // [6, 0, 18]
var double = arr.map(v =&gt; v * 2);       // [10, 12, 26, 0, 2, 36, 46]

// Le catene di promise sono più concise
promise.then(a =&gt; {
  // ...
}).then(b =&gt; {
   // ...
});

// le funzioni a freccia senza parametri sono più semplici da visualizzare
setTimeout( _ =&gt; {
  console.log("I happen sooner");
  setTimeout( _ =&gt; {
    // 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 =&gt; {}</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>