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
|
---
title: Classes
slug: Web/JavaScript/Reference/Classes
tags:
- Classes
- ECMAScript6
- Experimental
- Inheritance
- Intermediate
- JavaScript
- NeedsContent
- NeedsTranslation
- Reference
- TopicStub
translation_of: Web/JavaScript/Reference/Classes
---
<div>{{JsSidebar("Classes")}}</div>
<p>Le classi JavaScript, introdotte in ECMAScript 2015, sono principalmente zucchero sintattico sull'esistente ereditarietà prototipale di JavaScript. La sintassi <em>non</em><strong> </strong>introduce un nuovo modello di eredità orientata agli oggetti in JavaScript.</p>
<h2 id="Definizione_classi">Definizione classi</h2>
<p>Le classi sono di fatto delle "<a href="/en-US/docs/Web/JavaScript/Reference/Functions">funzioni</a> speciali", e così come puoi definire <a href="/en-US/docs/Web/JavaScript/Reference/Operators/function">function expressions</a> e <a href="/en-US/docs/Web/JavaScript/Reference/Statements/function">function declarations</a>, la sintassi per la classe ha due componenti: <a href="/en-US/docs/Web/JavaScript/Reference/Operators/class">class expressions</a> e <a href="/en-US/docs/Web/JavaScript/Reference/Statements/class">class declarations</a>.</p>
<h3 id="Dichiarazione_classe">Dichiarazione classe</h3>
<p>Un modo per definire una classe è quello di <strong>dichiararla</strong>. Per dichiarare una classe, usa la <em>keyword</em> <code>class</code> seguito dal nome della classe (in questo caso "Polygon").</p>
<pre class="brush: js">class Polygon {
constructor(height, width) {
this.height = height;
this.width = width;
}
}</pre>
<h4 id="Hoisting">Hoisting</h4>
<p>Un'importante differenza tra la <strong>dichiarazione di una funzione</strong> e la <strong>dichiarazione di una classe</strong> è che le dichiarazioni di funzione sono {{Glossary("Hoisting", "hoisted")}} mentre quelle per le classi no. Bisogna dichiarare la classe e poi si può usarla, altrimenti il codice solleva un'eccezione {{jsxref("ReferenceError")}}:</p>
<pre class="brush: js example-bad">var p = new Polygon(); // ReferenceError
class Polygon {}
</pre>
<h3 id="Class_expressions">Class expressions</h3>
<p>Una <strong>class expression</strong> è un altro modo di definire una classe. In questo caso possono avere un nome o meno. Il nome dato è locale al corpo della classe.</p>
<pre class="brush: js">// unnamed
var Polygon = class {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
// named
var Polygon = class Polygon {
constructor(height, width) {
this.height = height;
this.width = width;
}
};
</pre>
<p><strong>Nota: </strong>anche le <strong>Class</strong> <strong>expressions </strong>soffrono degli stessi problemi di hoisting menzionati per le <strong>dichiarazioni di Classi.</strong></p>
<h2 id="Corpo_della_classe_e_definizione_dei_metodi">Corpo della classe e definizione dei metodi</h2>
<p>Il corpo di una classe è la parte inclusa tra le parentesi graffe <code>{}</code>. Qui si definiscono i membri della classe come il costruttore o i metodi.</p>
<h3 id="Strict_mode">Strict mode</h3>
<p>I corpi di <em>class declarations</em> e <em>class expression</em> sono eseguiti in <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode">strict mode</a>.</p>
<h3 id="Costruttore">Costruttore</h3>
<p>Il <code><a href="/en-US/docs/Web/JavaScript/Reference/Classes/constructor">costruttore</a></code> è un metodo speciale usato per creare ed inizializzare un oggetto. Ci può essere un solo metodo con il nome "constructor" in una classe. Se la classe contiene più di un'occorrenza del costruttore verrà sollevato un {{jsxref("SyntaxError")}}.</p>
<p>Un costruttore può usare la parola chiave <code>super</code> per richiamare il costruttore della classe padre.</p>
<h3 id="Prototipi">Prototipi</h3>
<p>Guarda anche <a href="/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions">method definitions</a>.</p>
<pre class="brush: js">class Polygon {
constructor(height, width) {
this.height = height;
this.width = width;
}
get area() {
return this.calcArea()
}
calcArea() {
return this.height * this.width;
}
}</pre>
<h3 id="Metodi_statici">Metodi statici</h3>
<p>La parola chiave <code><a href="/en-US/docs/Web/JavaScript/Reference/Classes/static">static</a></code> definisce un metodo statico. I metodi statici sono chiamati senza istanziare la loro classe e <strong>non</strong> possono essere chiamati su una classe istanziata. Vengono usati per creare funzioni di utilità.</p>
<pre class="brush: js">class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
static distance(a, b) {
const dx = a.x - b.x;
const dy = a.y - b.y;
return Math.sqrt(dx*dx + dy*dy);
}
}
const p1 = new Point(5, 5);
const p2 = new Point(10, 10);
console.log(Point.distance(p1, p2));</pre>
<h3 id="Inscatolamento_con_metodi_prototipo_e_statico">Inscatolamento con metodi prototipo e statico</h3>
<p>Quando un metodo statico o prototipo è chiamato senza un oggetto valutato "this", allora il valore di "this" sarà <code><strong>undefined</strong></code> all'interno della funzione chiamata. L'autoinscatolamento non succederà. Il comportamento sarà lo stesso perfino se scriviamo il codice in modalità non-strict perché tutte le funzioni, metodi, costruttori, getter o setter sono eseguiti in modo strict. Così se non specifichiamo il valore <em>this</em>, allora sarà <code><strong>undefined.</strong></code></p>
<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">class</span> <span class="class-name token">Animal</span> <span class="punctuation token">{</span>
<span class="function token">speak</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="keyword token">return</span> <span class="keyword token">this</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span>
<span class="keyword token">static</span> <span class="function token">eat</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="keyword token">return</span> <span class="keyword token">this</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span>
<span class="punctuation token">}</span>
<span class="keyword token">let</span> obj <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">Animal</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
obj<span class="punctuation token">.</span><span class="function token">speak</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// Animal {}</span>
<span class="keyword token">let</span> speak <span class="operator token">=</span> obj<span class="punctuation token">.</span>speak<span class="punctuation token">;</span>
<span class="function token">speak</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// undefined</span>
Animal<span class="punctuation token">.</span><span class="function token">eat</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="comment token">// class Animal</span>
<span class="keyword token">let</span> eat <span class="operator token">=</span> Animal<span class="punctuation token">.</span>eat<span class="punctuation token">;</span>
<span class="function token">eat</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// undefined</span></code></pre>
<p>Se scriviamo il codice soprascritto usando le tradizionali classi basate su funzioni, allora l'autoinscatolamento accadrà basato sul valore "this" peril quale la funzione è stata chiamata.</p>
<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">function</span> <span class="function token">Animal</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> <span class="punctuation token">}</span>
Animal<span class="punctuation token">.</span>prototype<span class="punctuation token">.</span>speak <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="keyword token">return</span> <span class="keyword token">this</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span>
Animal<span class="punctuation token">.</span>eat <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="keyword token">return</span> <span class="keyword token">this</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span>
<span class="keyword token">let</span> obj <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">Animal</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="keyword token">let</span> speak <span class="operator token">=</span> obj<span class="punctuation token">.</span>speak<span class="punctuation token">;</span>
<span class="function token">speak</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// global object</span>
<span class="keyword token">let</span> eat <span class="operator token">=</span> Animal<span class="punctuation token">.</span>eat<span class="punctuation token">;</span>
<span class="function token">eat</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// global object</span></code></pre>
<h2 id="Sottoclassi_con_extends">Sottoclassi con <code>extends</code></h2>
<p>La keyword <code><a href="/en-US/docs/Web/JavaScript/Reference/Classes/extends">extends</a></code> viene usata<code><a href="/en-US/docs/Web/JavaScript/Reference/Classes/extends"> </a></code>nelle <em>class declarations</em> o <em>class expressions </em>per creare una classe figlia di un'altra classe.</p>
<pre class="brush: js">class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Dog extends Animal {
speak() {
console.log(this.name + ' barks.');
}
}
</pre>
<p>Si possono anche estendere le classi tradizionali basate su funzioni:</p>
<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">function</span> Animal <span class="punctuation token">(</span>name<span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="keyword token">this</span><span class="punctuation token">.</span>name <span class="operator token">=</span> name<span class="punctuation token">;</span>
<span class="punctuation token">}</span>
Animal<span class="punctuation token">.</span>prototype<span class="punctuation token">.</span>speak <span class="operator token">=</span> <span class="keyword token">function</span> <span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span>
console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span><span class="keyword token">this</span><span class="punctuation token">.</span>name <span class="operator token">+</span> <span class="string token">' makes a noise.'</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span>
<span class="keyword token">class</span> <span class="class-name token">Dog</span> <span class="keyword token">extends</span> <span class="class-name token">Animal</span> <span class="punctuation token">{</span>
<span class="function token">speak</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span>
<span class="keyword token">super</span><span class="punctuation token">.</span><span class="function token">speak</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span><span class="keyword token">this</span><span class="punctuation token">.</span>name <span class="operator token">+</span> <span class="string token">' barks.'</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
<span class="punctuation token">}</span>
<span class="punctuation token">}</span>
<span class="keyword token">var</span> d <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">Dog</span><span class="punctuation token">(</span><span class="string token">'Mitzie'</span><span class="punctuation token">)</span><span class="punctuation token">;</span>
d<span class="punctuation token">.</span><span class="function token">speak</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre>
<h2 id="Sub_classing_built-in_objects">Sub classing built-in objects</h2>
<p>TBD</p>
<h2 id="Chiamare_una_superclasse_con_super">Chiamare una superclasse con <code>super</code></h2>
<p>La keyword <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/super">super</a></code> è usata per chiamare le funzioni di un oggetto padre.</p>
<pre class="brush: js">class Cat {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Lion extends Cat {
speak() {
super.speak();
console.log(this.name + ' roars.');
}
}
</pre>
<h2 id="ES5_inheritance_syntax_and_ES6_classes_syntax_compared">ES5 inheritance syntax and ES6 classes syntax compared</h2>
<p>TBD</p>
<h2 id="Esempi">Esempi</h2>
<p>TBD</p>
<h2 id="Specifications">Specifications</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-class-definitions', 'Class definitions')}}</td>
<td>{{Spec2('ES6')}}</td>
<td>Initial definition.</td>
</tr>
</tbody>
</table>
<h2 id="Browser_compatibili">Browser compatibili</h2>
<p>{{Compat("javascript.classes")}}</p>
<h2 id="See_also">See also</h2>
<ul>
<li><a href="/en-US/docs/Web/JavaScript/Reference/Functions">Fun</a>zioni</li>
<li>{{jsxref("Statements/class", "class declaration")}}</li>
<li>{{jsxref("Operators/class", "class expression")}}</li>
<li>{{jsxref("Operators/super", "super")}}</li>
<li><a href="https://hacks.mozilla.org/2015/07/es6-in-depth-classes/">Blog post: "ES6 In Depth: Classes"</a></li>
</ul>
|