Skip to content

Commit 8020a94

Browse files
committed
translated article
1 parent 67a15a5 commit 8020a94

File tree

1 file changed

+80
-80
lines changed
  • 1-js/08-prototypes/01-prototype-inheritance

1 file changed

+80
-80
lines changed

1-js/08-prototypes/01-prototype-inheritance/article.md

Lines changed: 80 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
# Prototypal inheritance
22

3-
In programming, we often want to take something and extend it.
3+
Nella programmazione, spesso vogliamo prendere qualcosa ed estenderlo.
44

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.
66

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.
88

99
## [[Prototype]]
1010

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):
1212

1313
![prototype](object-prototype-empty.svg)
1414

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.
1616

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.
1818

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:
2020

2121
```js run
2222
let animal = {
@@ -27,13 +27,13 @@ let rabbit = {
2727
};
2828

2929
*!*
30-
rabbit.__proto__ = animal; // sets rabbit.[[Prototype]] = animal
30+
rabbit.__proto__ = animal; // imposta il prototy di rabbit,.[[Prototype]] = animal
3131
*/!*
3232
```
3333

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`.
3535

36-
For instance:
36+
Ad esempio:
3737

3838
```js
3939
let animal = {
@@ -47,24 +47,24 @@ let rabbit = {
4747
rabbit.__proto__ = animal; // (*)
4848
*/!*
4949

50-
// we can find both properties in rabbit now:
50+
// ora in rabbit possiamo trovare entrambe le proprietà
5151
*!*
5252
alert( rabbit.eats ); // true (**)
5353
*/!*
5454
alert( rabbit.jumps ); // true
5555
```
5656

57-
Here the line `(*)` sets `animal` to be a prototype of `rabbit`.
57+
Nell'esempio la linea `(*)` imposta `animal` come prototype di `rabbit`.
5858

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):
6060

6161
![](proto-animal-rabbit.svg)
6262

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`"
6464

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".
6666

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`:
6868

6969
```js run
7070
let animal = {
@@ -81,17 +81,17 @@ let rabbit = {
8181
__proto__: animal
8282
};
8383

84-
// walk is taken from the prototype
84+
// walk viene ereditato dal prototype
8585
*!*
8686
rabbit.walk(); // Animal walk
8787
*/!*
8888
```
8989

90-
The method is automatically taken from the prototype, like this:
90+
Il metodo viene preso automaticamente dal prototipo, in questo modo:
9191

9292
![](proto-animal-rabbit-walk.svg)
9393

94-
The prototype chain can be longer:
94+
La catena dei prototype può esser anche più lunga:
9595

9696
```js run
9797
let animal = {
@@ -115,48 +115,48 @@ let longEar = {
115115
*/!*
116116
};
117117

118-
// walk is taken from the prototype chain
118+
// walk viene presa dalla catena di prototype
119119
longEar.walk(); // Animal walk
120-
alert(longEar.jumps); // true (from rabbit)
120+
alert(longEar.jumps); // true (da rabbit)
121121
```
122122

123123
![](proto-animal-rabbit-chain.svg)
124124

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`.
126126

127-
There are only two limitations:
127+
Ci sono solamente due limitazioni:
128128

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.
131131

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.
133133

134134

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.
137137

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.
139139

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.
141141

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.
143143

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.
145145
```
146146
147-
## Writing doesn't use prototype
147+
## La scrittura non utilizza prototype
148148
149-
The prototype is only used for reading properties.
149+
Il prototype viene utilizzato solamente per la lettura delle proprietà.
150150
151-
Write/delete operations work directly with the object.
151+
Le operazioni di scrittura/rimozione utilizzano direttamente l'oggetto.
152152
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`:
154154
155155
```js run
156156
let animal = {
157157
eats: true,
158158
walk() {
159-
/* this method won't be used by rabbit */
159+
/* questo metodo non verrà utilizzato da rabbit */
160160
}
161161
};
162162
@@ -173,13 +173,13 @@ rabbit.walk = function() {
173173
rabbit.walk(); // Rabbit! Bounce-bounce!
174174
```
175175

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:
177177

178178
![](proto-animal-rabbit-walk-2.svg)
179179

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.
181181

182-
For that reason `admin.fullName` works correctly in the code below:
182+
Per questo motivo, `admin.fullName` funziona correttamente nel codice sotto:
183183

184184
```js run
185185
let user = {
@@ -202,33 +202,33 @@ let admin = {
202202

203203
alert(admin.fullName); // John Smith (*)
204204

205-
// setter triggers!
205+
// il setter viene invocato!
206206
admin.fullName = "Alice Cooper"; // (**)
207207

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
210210
```
211211

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.
213213

214-
## The value of "this"
214+
## Il valore di "this"
215215

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`?
217217

218-
The answer is simple: `this` is not affected by prototypes at all.
218+
La risposta è semplice: `this` non viene influenzato dai prototype.
219219

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.**
221221

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`.
223223

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.
225225

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.
227227

228-
The call `rabbit.sleep()` sets `this.isSleeping` on the `rabbit` object:
228+
La chiamata `rabbit.sleep()` imposta `this.isSleeping` nell'oggetto `rabbit`:
229229

230230
```js run
231-
// animal has methods
231+
// animal possiede dei metodi
232232
let animal = {
233233
walk() {
234234
if (!this.isSleeping) {
@@ -245,26 +245,26 @@ let rabbit = {
245245
__proto__: animal
246246
};
247247

248-
// modifies rabbit.isSleeping
248+
// modifica rabbit.isSleeping
249249
rabbit.sleep();
250250

251251
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)
253253
```
254254

255-
The resulting picture:
255+
Il risultato:
256256

257257
![](proto-animal-rabbit-walk-3.svg)
258258

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.
260260

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 è.
262262

263-
## for..in loop
263+
## Il ciclo for..in
264264

265-
The `for..in` loop iterates over inherited properties too.
265+
Il ciclo `for..in` itera anche le proprietà ereditate.
266266

267-
For instance:
267+
Ad esempio:
268268

269269
```js run
270270
let animal = {
@@ -277,19 +277,19 @@ let rabbit = {
277277
};
278278

279279
*!*
280-
// Object.keys only returns own keys
280+
// Object.keys ritorna solamente le chiavi
281281
alert(Object.keys(rabbit)); // jumps
282282
*/!*
283283

284284
*!*
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
286286
for(let prop in rabbit) alert(prop); // jumps, then eats
287287
*/!*
288288
```
289289

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).
291291

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):
293293

294294
```js run
295295
let animal = {
@@ -312,28 +312,28 @@ for(let prop in rabbit) {
312312
}
313313
```
314314

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`:
316316

317317
![](rabbit-animal-object.svg)
318318

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.
320320

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?
322322

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.
324324

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.
327327
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.
329329
```
330330

331-
## Summary
331+
## Riepilogo
332332

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

Comments
 (0)