You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 1-js/08-prototypes/01-prototype-inheritance/article.md
+80-80Lines changed: 80 additions & 80 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,22 +1,22 @@
1
1
# Prototypal inheritance
2
2
3
-
In programming, we often want to take something and extend it.
3
+
Nella programmazione, spesso vogliamo prendere qualcosa ed estenderlo.
4
4
5
-
For instance, we have a `user`object with its properties and methods, and want to make `admin`and`guest`as slightly modified variants of it. We'd like to reuse what we have in`user`, not copy/reimplement its methods, just build a new object on top of it.
5
+
Ad esempio, potremmo avere un oggetto `user`con le sue proprietà e i suoi metodi, e voler definire gli oggetti `admin`e`guest`come sue varianti. Vorremmo però poter riutilizzare ciò che abbiamo nell'oggetto`user`, evitando di copiare e reimplementare nuovamente i suoi metodi, quindi vorremmo semplicemente definire un nuovo oggetto a partire da esso.
6
6
7
-
*Prototypal inheritance*is a language feature that helps in that.
7
+
La *prototypal inheritance*(ereditarietà dei prototype) è una caratteristica del linguaggio che aiuta in questo senso.
8
8
9
9
## [[Prototype]]
10
10
11
-
In JavaScript, objects have a special hidden property `[[Prototype]]` (as named in the specification), that is either`null`or references another object. That object is called "a prototype":
11
+
In JavaScript, possiedono una speciale proprietà nascosta `[[Prototype]]` (come definito nella specifica), questo puo valere`null`oppure puo contenere il riferimento ad un altro oggetto. Quell'oggetto viene definito "prototype" (prototipo):
12
12
13
13

14
14
15
-
When we read a property from `object`, and it's missing, JavaScript automatically takes it from the prototype. In programming, such thing is called "prototypal inheritance". And soon we'll study many examples of such inheritance, as well as cooler language features built upon it.
15
+
Quando leggiamo una proprietà da `object`, e questa non esiste, JavaScript prova automaticamente a recuperarla dal suo prototype. In programmazione, questo comportamento viene definito "prototypal inheritance". Presto vederemo diversi esempi di questo tipo di ereditarietà, e vedremo anche delle interessanti caratteristiche di linguaggio basate su di essa.
16
16
17
-
The property`[[Prototype]]`is internal and hidden, but there are many ways to set it.
17
+
La proprietà`[[Prototype]]`è interna e nascosta, ma esistono diversi modi per poterla impostare.
18
18
19
-
One of them is to use the special name `__proto__`, like this:
19
+
Uno di questi è quello di utilizzare la nomenclatura speciale `__proto__`, in questo modo:
rabbit.__proto__= animal; //imposta il prototy di rabbit,.[[Prototype]] = animal
31
31
*/!*
32
32
```
33
33
34
-
Now if we read a property from `rabbit`, and it's missing, JavaScript will automatically take it from`animal`.
34
+
Ora se proviamo a leggere una proprietà da `rabbit`, e questa risulta essere mancante, JavaScript andrà a prenderla automaticamente da`animal`.
35
35
36
-
For instance:
36
+
Ad esempio:
37
37
38
38
```js
39
39
let animal = {
@@ -47,24 +47,24 @@ let rabbit = {
47
47
rabbit.__proto__= animal; // (*)
48
48
*/!*
49
49
50
-
//we can find both properties in rabbit now:
50
+
//ora in rabbit possiamo trovare entrambe le proprietà
51
51
*!*
52
52
alert( rabbit.eats ); // true (**)
53
53
*/!*
54
54
alert( rabbit.jumps ); // true
55
55
```
56
56
57
-
Here the line`(*)`sets`animal`to be a prototype of`rabbit`.
57
+
Nell'esempio la linea`(*)`imposta`animal`come prototype di`rabbit`.
58
58
59
-
Then, when`alert`tries to read property `rabbit.eats``(**)`, it's not in `rabbit`, so JavaScript follows the `[[Prototype]]`reference and finds it in `animal` (look from the bottom up):
59
+
Successivamente, quando`alert`proverà a leggere la proprietà `rabbit.eats``(**)`, non la troverà in rabbit, quindi JavaScript seguirà il riferimento in `[[Prototype]]`e la troverà in `animal` (ricerca dal basso verso l'alto):
60
60
61
61

62
62
63
-
Here we can say that "`animal`is the prototype of`rabbit`" or "`rabbit` prototypically inherits from `animal`".
63
+
In questo caso possiamo dire che "`animal`è il prototype di`rabbit`" o, in alternativa, che "`rabbit` prototypically inherits (eredità dal prototipo) da `animal`"
64
64
65
-
So if`animal`has a lot of useful properties and methods, then they become automatically available in `rabbit`. Such properties are called "inherited".
65
+
Quindi se`animal`possiede molte proprietà e metodi utili, questi saranno automaticamente disponibili in `rabbit`. Queste proprietà vengono definite come "ereditate".
66
66
67
-
If we have a method in `animal`, it can be called on`rabbit`:
67
+
Se abbiamo un metodo in `animal`, possiamo invocarlo anche in`rabbit`:
68
68
69
69
```js run
70
70
let animal = {
@@ -81,17 +81,17 @@ let rabbit = {
81
81
__proto__: animal
82
82
};
83
83
84
-
// walk is taken from the prototype
84
+
// walk viene ereditato dal prototype
85
85
*!*
86
86
rabbit.walk(); // Animal walk
87
87
*/!*
88
88
```
89
89
90
-
The method is automatically taken from the prototype, like this:
90
+
Il metodo viene preso automaticamente dal prototipo, in questo modo:
91
91
92
92

93
93
94
-
The prototype chain can be longer:
94
+
La catena dei prototype può esser anche più lunga:
95
95
96
96
```js run
97
97
let animal = {
@@ -115,48 +115,48 @@ let longEar = {
115
115
*/!*
116
116
};
117
117
118
-
// walk is taken from the prototype chain
118
+
// walk viene presa dalla catena di prototype
119
119
longEar.walk(); // Animal walk
120
-
alert(longEar.jumps); // true (from rabbit)
120
+
alert(longEar.jumps); // true (da rabbit)
121
121
```
122
122
123
123

124
124
125
-
Now if we read something from `longEar`, and it's missing, JavaScript will look for it in `rabbit`, and then in `animal`.
125
+
Ora, se provassimo a leggere qualcosa da `longEar`, e non esistesse, JavaScript andrebbe a guardare prima in `rabbit`, e poi in `animal`.
126
126
127
-
There are only two limitations:
127
+
Ci sono solamente due limitazioni:
128
128
129
-
1.The references can't go in circles. JavaScript will throw an error if we try to assign `__proto__`in a circle.
130
-
2.The value of`__proto__`can be either an object or`null`. Other types are ignored.
129
+
1.Non possono esserci riferimenti circolari. JavaScript lancerebbe un errore se provassimo ad assegnare a `__proto__`un riferimento circolare.
130
+
2.Il valore di`__proto__`può essere o un oggetto o`null`. Gli altri valore vengono ignorati.
131
131
132
-
Also it may be obvious, but still: there can be only one `[[Prototype]]`. An object may not inherit from two others.
132
+
Inoltre, anche se dovrebbe essere già ovvio: può esserci solamente un `[[Prototype]]`. Un oggetto non può eridatare da più oggetti.
133
133
134
134
135
-
```smart header="`__proto__`is a historical getter/setter for`[[Prototype]]`"
136
-
It's a common mistake of novice developers not to know the difference between these two.
135
+
```smart header="`__proto__`è un getter/setter storico per`[[Prototype]]`"
136
+
E' un errore comune tra i principianti quello di non conoscere la differenza tra questi due.
137
137
138
-
Please note that`__proto__`is *not the same* as the internal `[[Prototype]]` property. It's a getter/setter for`[[Prototype]]`. Later we'll see situations where it matters, for now let's just keep it in mind, as we build our understanding of JavaScript language.
138
+
Da notare che`__proto__`non è *la stessa cosa* della proprietà `[[Prototype]]`. E' solamente un getter/setter per`[[Prototype]]`. Più avanti vedremo alcune situazioni in cui questa differenza avrà importanza, quando avremo una buona conoscenza del linguaggio JavaScript.
139
139
140
-
The `__proto__`property is a bit outdated. It exists for historical reasons, modern JavaScript suggests that we should use`Object.getPrototypeOf/Object.setPrototypeOf`functions instead that get/set the prototype. We'll also cover these functions later.
140
+
La proprietà `__proto__`è leggermente datata. Esiste solamente per ragioni storiche, la versione attuale di JavaScript suggerisce di utilizzare le funzioni`Object.getPrototypeOf/Object.setPrototypeOf`per impostare il prototype. Vedremo meglio queste funzioni più avanti.
141
141
142
-
By the specification, `__proto__`must only be supported by browsers. In fact though, all environments including server-side support`__proto__`, so we're quite safe using it.
142
+
Secondo la specifica, `__proto__`deve essere supportato solamente dai browser. In realtà, tutti gli ambienti, inclusi quelli server-side, supportano`__proto__`, quindi il suo utilizzo è piuttosto sicuro.
143
143
144
-
As the `__proto__`notation is a bit more intuitively obvious, we use it in the examples.
144
+
Poichè la notazione `__proto__`risulta essere più intuitiva, la utilizzeremo nei nostri esempi.
145
145
```
146
146
147
-
## Writing doesn't use prototype
147
+
## La scrittura non utilizza prototype
148
148
149
-
The prototype is only used for reading properties.
149
+
Il prototype viene utilizzato solamente per la lettura delle proprietà.
150
150
151
-
Write/delete operations work directly with the object.
151
+
Le operazioni di scrittura/rimozione utilizzano direttamente l'oggetto.
152
152
153
-
In the example below, we assign its own `walk` method to `rabbit`:
153
+
Nell'esempio che vediamo sotto, assegniamo un suo metodo `walk` a `rabbit`:
154
154
155
155
```js run
156
156
let animal = {
157
157
eats: true,
158
158
walk() {
159
-
/* this method won't be used by rabbit */
159
+
/* questo metodo non verrà utilizzato da rabbit */
160
160
}
161
161
};
162
162
@@ -173,13 +173,13 @@ rabbit.walk = function() {
173
173
rabbit.walk(); // Rabbit! Bounce-bounce!
174
174
```
175
175
176
-
From now on, `rabbit.walk()`call finds the method immediately in the object and executes it, without using the prototype:
176
+
Da questo punto in poi, la chiamata `rabbit.walk()`troverà il metodo direttamente nell'oggetto e lo eseguirà, senza utilizare il prototype:
177
177
178
178

179
179
180
-
Accessor properties are an exception, as assignment is handled by a setter function. So writing to such a property is actually the same as calling a function.
180
+
Le proprietà di accesso sono delle eccezioni, poiché l'assegnazione viene gestita da un setter. Quindi scrivere su una proprietà di questo tipo equivale ad invocare una funzione.
181
181
182
-
For that reason`admin.fullName`works correctly in the code below:
182
+
Per questo motivo,`admin.fullName`funziona correttamente nel codice sotto:
183
183
184
184
```js run
185
185
let user = {
@@ -202,33 +202,33 @@ let admin = {
202
202
203
203
alert(admin.fullName); // John Smith (*)
204
204
205
-
// setter triggers!
205
+
//il setter viene invocato!
206
206
admin.fullName="Alice Cooper"; // (**)
207
207
208
-
alert(admin.fullName); // Alice Cooper, state of admin modified
209
-
alert(user.fullName); // John Smith, state of user protected
208
+
alert(admin.fullName); // Alice Cooper, lo stato di admin è stato modificato
209
+
alert(user.fullName); // John Smith, lo stato di user è protetto
210
210
```
211
211
212
-
Here in the line `(*)`the property`admin.fullName`has a getter in the prototype `user`, so it is called. And in the line `(**)`the property has a setter in the prototype, so it is called.
212
+
Nell'esempio in linea `(*)`la proprietà`admin.fullName`possiede un getter nel prototype `user`, quindi viene invocato. In linea `(**)`la proprietà ha un setter nel prototype, che viene quindi invocato.
213
213
214
-
## The value of "this"
214
+
## Il valore di "this"
215
215
216
-
An interesting question may arise in the example above: what's the value of`this`inside`set fullName(value)`? Where are the properties `this.name`and`this.surname` written: into`user`or`admin`?
216
+
Dall'esempio sopra potrebbe sorgere una domanda interessante: qual'è il valore di`this`all'interno`set fullName(value)`? Dove vengono scritte le proprietà `this.name`e`this.surname`: in`user`o`admin`?
217
217
218
-
The answer is simple: `this`is not affected by prototypes at all.
218
+
La risposta è semplice: `this`non viene influenzato dai prototype.
219
219
220
-
**No matter where the method is found: in an object or its prototype. In a method call, `this`is always the object before the dot.**
220
+
**Non ha importanza dove viene trovato il metodo: nell'oggetto o in un suo prototupe. Quando invochiamo un metodo, `this`fa sempre riferimento all'oggetto che precede il punto.**
221
221
222
-
So, the setter call `admin.fullName=`uses`admin`as`this`, not`user`.
222
+
Quindi, l'invocazione del setter `admin.fullName=`utilizza`admin`come`this`, non`user`.
223
223
224
-
That is actually a super-important thing, because we may have a big object with many methods, and have objects that inherit from it. And when the inheriting objects run the inherited methods, they will modify only their own states, not the state of the big object.
224
+
Questo è molto importante, poiché potremmo avere un oggetto molto grande con molti metodi, e avere diversi oggetti che ereditano da esso. Quando gli oggetti che ereditano, eseguono un metodo ereditato, andranno a modificare solamente il loro stato, non quello dell'oggetto principale.
225
225
226
-
For instance, here`animal`represents a "method storage", and`rabbit`makes use of it.
226
+
Ad esempio, qui`animal`rappresenta un "memorizzato di metodi", che`rabbit`utilizza.
227
227
228
-
The call`rabbit.sleep()`sets`this.isSleeping`on the `rabbit` object:
228
+
La chiamata`rabbit.sleep()`imposta`this.isSleeping`nell'oggetto `rabbit`:
229
229
230
230
```js run
231
-
// animal has methods
231
+
// animal possiede dei metodi
232
232
let animal = {
233
233
walk() {
234
234
if (!this.isSleeping) {
@@ -245,26 +245,26 @@ let rabbit = {
245
245
__proto__: animal
246
246
};
247
247
248
-
//modifies rabbit.isSleeping
248
+
//modifica rabbit.isSleeping
249
249
rabbit.sleep();
250
250
251
251
alert(rabbit.isSleeping); // true
252
-
alert(animal.isSleeping); // undefined (no such property in the prototype)
252
+
alert(animal.isSleeping); // undefined (non esiste questa proprietà nel prototype)
253
253
```
254
254
255
-
The resulting picture:
255
+
Il risultato:
256
256
257
257

258
258
259
-
If we had other objects, like`bird`, `snake`, etc., inheriting from `animal`, they would also gain access to methods of`animal`. But `this`in each method call would be the corresponding object, evaluated at the call-time (before dot), not `animal`. So when we write data into `this`, it is stored into these objects.
259
+
Se avessimo altri oggetti, come`bird`, `snake`, etc., che ereditano da `animal`, avrebbero a loro volta accesso ai metodi di`animal`. In ogni caso, `this`all'interno della chiamata, farebbere riferimento all'oggetto corrispondente, che viene valutato al momento dell'invocazione (appena prima del punto), e non ad `animal`. Quindi quando scriviamo dati utilizzando `this`, questi verranno memorizzati nell'oggetto corrispondente.
260
260
261
-
As a result, methods are shared, but the object state is not.
261
+
Come risultato otteniamo che dei metodi condivisi, mentre lo stato degli oggetti non lo è.
262
262
263
-
## for..in loop
263
+
## Il ciclo for..in
264
264
265
-
The `for..in`loop iterates over inherited properties too.
265
+
Il ciclo `for..in`itera anche le proprietà ereditate.
266
266
267
-
For instance:
267
+
Ad esempio:
268
268
269
269
```js run
270
270
let animal = {
@@ -277,19 +277,19 @@ let rabbit = {
277
277
};
278
278
279
279
*!*
280
-
// Object.keys only returns own keys
280
+
// Object.keys ritorna solamente le chiavi
281
281
alert(Object.keys(rabbit)); // jumps
282
282
*/!*
283
283
284
284
*!*
285
-
// for..in loops over both own and inherited keys
285
+
//il ciclo for..in itera sia le proprietà di rabbi, che quelle ereditate da animal
286
286
for(let prop in rabbit) alert(prop); // jumps, then eats
287
287
*/!*
288
288
```
289
289
290
-
If that's not what we want, and we'd like to exclude inherited properties, there's a built-in method[obj.hasOwnProperty(key)](mdn:js/Object/hasOwnProperty): it returns `true`if`obj`has its own (not inherited) property named `key`.
290
+
Se questo non è ciò che ci aspettiamo, e voglia escludere le proprietà ereditate, esiste un metodo integrato[obj.hasOwnProperty(key)](mdn:js/Object/hasOwnProperty): ritorna `true`se`obj`possiede la proprietà `key` come non ereditata (propria).
291
291
292
-
So we can filter out inherited properties (or do something else with them):
292
+
Quindi possiamo filtrare le proprietà ereditate (o farci qualcos altro):
293
293
294
294
```js run
295
295
let animal = {
@@ -312,28 +312,28 @@ for(let prop in rabbit) {
312
312
}
313
313
```
314
314
315
-
Here we have the following inheritance chain: `rabbit`inherits from`animal`, that inherits from`Object.prototype` (because`animal`is a literal object`{...}`, so it's by default), and then`null` above it:
315
+
Qui abbiamo la seguente catena di ereditarietà: `rabbit`eredita da`animal`, che eredita da`Object.prototype` (poiché`animal`è un *literal objects*`{...}`), e infine`null`:
316
316
317
317

318
318
319
-
Note, there's one funny thing. Where is the method `rabbit.hasOwnProperty` coming from? We did not define it. Looking at the chain we can see that the method is provided by `Object.prototype.hasOwnProperty`. In other words, it's inherited.
319
+
Da notare, c'è una cosa divertente. Da dove arriva il metodo `rabbit.hasOwnProperty`? Noi non lo abbiamo mai definito. Osservando la catena ci accorgiamo che il metodo viene fornito da `Object.prototype.hasOwnProperty`. In altre parole, è ereditato.
320
320
321
-
...But why does `hasOwnProperty`not appear in the`for..in`loop like `eats`and`jumps` do, if`for..in`lists inherited properties?
321
+
...Ma perché `hasOwnProperty`non appare nel ciclo`for..in`come `eats`e`jumps`, se`for..in`elenca tutte le proprietà ereditate?
322
322
323
-
The answer is simple: it's not enumerable. Just like all other properties of`Object.prototype`, it has `enumerable:false` flag. And`for..in`only lists enumerable properties. That's why it and the rest of the `Object.prototype`properties are not listed.
323
+
La risposta è semplice: la proprietà è *non enumerable*. Come tutte le altre proprietà di`Object.prototype`, possiedono la flag `enumerable:false`. Quindi`for..in`elenca solamente le proprietà enumerable. Questo è il motivo per cui le proprietà di `Object.prototype`non vengono elencate.
324
324
325
-
```smart header="Almost all other key/value-getting methods ignore inherited properties"
326
-
Almost all other key/value-getting methods, such as `Object.keys`, `Object.values` and so on ignore inherited properties.
325
+
```smart header="Quasi tutti gli altri metodi getter key-value ignorano le proprietà ereditate"
326
+
Quasi tutti gli altri metodi getter key-value, come `Object.keys`, `Object.values` e cosi via, ignorano le proprietà ereditate.
327
327
328
-
They only operate on the object itself. Properties from the prototype are *not* taken into account.
328
+
Questi metodi lavorano solamente sull'oggetto stesso. Le proprietà di prototype *non* vengono prese in considerazione.
329
329
```
330
330
331
-
## Summary
331
+
## Riepilogo
332
332
333
-
- In JavaScript, all objects have a hidden `[[Prototype]]`property that's either another object or`null`.
334
-
-We can use `obj.__proto__`to access it (a historical getter/setter, there are other ways, to be covered soon).
335
-
-The object referenced by `[[Prototype]]`is called a "prototype".
336
-
-If we want to read a property of `obj`or call a method, and it doesn't exist, then JavaScript tries to find it in the prototype.
337
-
-Write/delete operations act directly on the object, they don't use the prototype (assuming it's a data property, not a setter).
338
-
-If we call `obj.method()`, and the`method`is taken from the prototype, `this`still references `obj`. So methods always work with the current object even if they are inherited.
339
-
-The `for..in`loop iterates over both its own and its inherited properties. All other key/value-getting methods only operate on the object itself.
333
+
- In JavaScript, tutti gli oggetti possiedono una proprietà nascosta `[[Prototype]]`che può essere il riferimento ad un altro oggetto, oppure`null`.
334
+
-Possiamo utilizzare `obj.__proto__`per accedervi (una proprietà getter/setter storica, ci sono altri modi che vederemo presto).
335
+
-L'oggetto a cui fa riferimento `[[Prototype]]`viene chiamato "prototype".
336
+
-Se vogliamo leggere una proprietà di `obj`o invocare un metodo, ma questo non esiste, allora JavaScript andrà a cercarlo nel prototype.
337
+
-Le operazioni di scrittrua/rimozione agiscono direttamente nell'oggetto, non utilizzano il prototype (assumendo che questa sia una proprietà e non un setter).
338
+
-Se invochiamo `obj.method()`, e il`method`viene prelevato dal prototype, `this`farà comunque riferimento a `obj`. Quindi i metodi lavoreranno sempre con l'oggetto corrente, anche se questi sono ereditati.
339
+
-Il ciclo `for..in`itera sia le proprietà dell'oggetto che quelle ereditate. Tutti gli altri metodi di tipo getter key/value operano solamente sull'oggetto stesso.
0 commit comments