Skip to content

Commit e0e0c6a

Browse files
authored
Merge pull request #242 from longo-andrea/article/mixins
Mixins
2 parents 45ce644 + 6a4c4d6 commit e0e0c6a

File tree

1 file changed

+50
-50
lines changed

1 file changed

+50
-50
lines changed
Lines changed: 50 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
11
# Mixins
22

3-
In JavaScript we can only inherit from a single object. There can be only one `[[Prototype]]` for an object. And a class may extend only one other class.
3+
In JavaScript possiamo ereditare solamente da un oggetto. Può esserci solamente un `[[Prototype]]` per oggetto. Ed una classe può estendere solamente un'altra classe.
44

5-
But sometimes that feels limiting. For instance, we have a class `StreetSweeper` and a class `Bicycle`, and want to make their mix: a `StreetSweepingBicycle`.
5+
In certi casi questo può essere un limite. Ad esempio, abbiamo una classe `StreetSweeper` ed una classe `Bicycle`, e vogliamo crearne un mix: un `StreetSweepingBicycle`.
66

7-
Or we have a class `User` and a class `EventEmitter` that implements event generation, and we'd like to add the functionality of `EventEmitter` to `User`, so that our users can emit events.
7+
Oppure abbiamo una classe `User` ed una classe `EventEmitter` che implementa la generazione degli eventi, e vorremmo poter aggiungere la funzionalità di `EventEmitter` a `User`, cosicché i nostri utenti possano emettere eventi.
88

9-
There's a concept that can help here, called "mixins".
9+
Esiste un concetto che può aiutare in questi casi, chiamato "mixins".
1010

11-
As defined in Wikipedia, a [mixin](https://en.wikipedia.org/wiki/Mixin) is a class containing methods that can be used by other classes without a need to inherit from it.
11+
Come definito in Wikipedia, un [mixin](https://en.wikipedia.org/wiki/Mixin) è una classe contenente metodi che possono essere utilizzati da altre classi, senza che ci sia la necessità di ereditare da questa classe.
1212

13-
In other words, a *mixin* provides methods that implement a certain behavior, but we do not use it alone, we use it to add the behavior to other classes.
13+
In altre parole, un *mixin* fornisce dei metodi che implementano delle funzionalità specifiche, che non andremo ad utilizzare da soli, ma piuttosto andremo ad aggiungere ad altre classi.
1414

15-
## A mixin example
15+
## Un esempio di mixin
1616

17-
The simplest way to implement a mixin in JavaScript is to make an object with useful methods, so that we can easily merge them into a prototype of any class.
17+
Il modo più semplice per implementare un mixin in JavaScript è quello di creare un oggetto con dei metodi utili, in questo modo potremo fonderli molto semplicemente nel prototype di un'altra classe.
1818

19-
For instance here the mixin `sayHiMixin` is used to add some "speech" for `User`:
19+
Ad esempio, qui vediamo il mixin `sayHiMixin` che viene utilizzato per aggiungere la funzionalità di "parlare" a `User`:
2020

2121
```js run
2222
*!*
@@ -32,22 +32,22 @@ let sayHiMixin = {
3232
};
3333

3434
*!*
35-
// usage:
35+
// utilizzo:
3636
*/!*
3737
class User {
3838
constructor(name) {
3939
this.name = name;
4040
}
4141
}
4242

43-
// copy the methods
43+
// copiamo i metodi
4444
Object.assign(User.prototype, sayHiMixin);
4545

46-
// now User can say hi
46+
// ora User può salutare
4747
new User("Dude").sayHi(); // Hello Dude!
4848
```
4949

50-
There's no inheritance, but a simple method copying. So `User` may inherit from another class and also include the mixin to "mix-in" the additional methods, like this:
50+
Non abbiamo utilizzato l'ereditarietà, ma abbiamo semplicemente copiato un metodo. Quindi `User` può tranquillamente ereditare da un'altra classe, ed includere il mixin per aggiungere funzionalità, come nell'esempio:
5151

5252
```js
5353
class User extends Person {
@@ -57,9 +57,9 @@ class User extends Person {
5757
Object.assign(User.prototype, sayHiMixin);
5858
```
5959

60-
Mixins can make use of inheritance inside themselves.
60+
I mixins possono utilizzare a loro volta l'ereditarietà.
6161

62-
For instance, here `sayHiMixin` inherits from `sayMixin`:
62+
Ad esempio, qui abbiamo `sayHiMixin` che erediata da `sayMixin`:
6363

6464
```js run
6565
let sayMixin = {
@@ -69,11 +69,11 @@ let sayMixin = {
6969
};
7070

7171
let sayHiMixin = {
72-
__proto__: sayMixin, // (or we could use Object.setPrototypeOf to set the prototype here)
72+
__proto__: sayMixin, // (oppure potremmo utilizzare Object.setPrototypeOf per impostare il prototype)
7373

7474
sayHi() {
7575
*!*
76-
// call parent method
76+
// invocazione del metodo genitore
7777
*/!*
7878
super.say(`Hello ${this.name}`); // (*)
7979
},
@@ -88,43 +88,43 @@ class User {
8888
}
8989
}
9090

91-
// copy the methods
91+
// copiamo i metodi
9292
Object.assign(User.prototype, sayHiMixin);
9393

94-
// now User can say hi
94+
// ora User può salutare
9595
new User("Dude").sayHi(); // Hello Dude!
9696
```
9797

98-
Please note that the call to the parent method `super.say()` from `sayHiMixin` (at lines labelled with `(*)`) looks for the method in the prototype of that mixin, not the class.
98+
Da notare che l'invocazione al metodo padre `super.say()` da `sayHiMixin` (alla riga etichettata con `(*)`) cerca il metodo nel prototype di quel mixin, non in quello della classe.
9999

100100
![](mixin-inheritance.svg)
101101

102102
![](mixin-inheritance.svg)
103103

104-
That's because methods `sayHi` and `sayBye` were initially created in `sayHiMixin`. So even though they got copied, their `[[HomeObject]]` internal property references `sayHiMixin`, as shown in the picture above.
104+
Questo accade perché i metodi `sayHi` e `sayBye` sono stati creati in `sayHiMixin`. Quindi, anche dopo essere stati copiati, le loro proprietà `[[HomeObject]]` fanno riferimento a `sayHiMixin`, come mostrato nella figura.
105105

106-
As `super` looks for parent methods in `[[HomeObject]].[[Prototype]]`, that means it searches `sayHiMixin.[[Prototype]]`, not `User.[[Prototype]]`.
106+
Poiché `super` ricerca i metodi in `[[HomeObject]].[[Prototype]]`, ciò significa che ricerca `sayHiMixin.[[Prototype]]`, non `User.[[Prototype]]`.
107107

108108
## EventMixin
109109

110-
Now let's make a mixin for real life.
110+
Ora creiamo un mixin per la vita reale.
111111

112-
An important feature of many browser objects (for instance) is that they can generate events. Events are a great way to "broadcast information" to anyone who wants it. So let's make a mixin that allows us to easily add event-related functions to any class/object.
112+
Una caratteristica importante di molti oggetti del browser (ad esempio) è che questi possono generare eventi. Gli eventi sono un'ottimo modo per "trasmettere informazioni" a chiunque ne sia interessato. Quindi creiamo un mixin che ci consenta di aggiungere funzioni relative agli eventi, ad una qualsiasi classe/oggetto.
113113

114-
- The mixin will provide a method `.trigger(name, [...data])` to "generate an event" when something important happens to it. The `name` argument is a name of the event, optionally followed by additional arguments with event data.
115-
- Also the method `.on(name, handler)` that adds `handler` function as the listener to events with the given name. It will be called when an event with the given `name` triggers, and get the arguments from the `.trigger` call.
116-
- ...And the method `.off(name, handler)` that removes the `handler` listener.
114+
- Il mixin fornirà un metodo `.trigger(name, [...data])` per "generare un evento" quando qualcosa di significativo accade. L'argomento `name` è il nome dell'evento, ed altri argomenti opzionali possono essere aggiunti con dati relativi all'evento.
115+
- Anche il metodo `.on(name, handler)`, che aggiunge una funzione `handler` come listener degli eventi con il nome fornito. Sarà invocato nel momento in cui un evento con il `name` fornito verrà invocato dalla chiamata `.trigger`.
116+
- ...Ed il metodo `.off(name, handler)` che rimuove il listener `handler`.
117117

118-
After adding the mixin, an object `user` will be able to generate an event `"login"` when the visitor logs in. And another object, say, `calendar` may want to listen for such events to load the calendar for the logged-in person.
118+
Dopo aver aggiunto il mixin, un oggetto `user` sarà in grado di generare un evento di `"login"` quando l'utente effettua l'accesso. Ed un altro oggetto, diciamo, `calendar` può stare in ascolto di questi eventi in modo da caricare il calendario della persona autenticata.
119119

120-
Or, a `menu` can generate the event `"select"` when a menu item is selected, and other objects may assign handlers to react on that event. And so on.
120+
Oppure un `menu` può generare un evento di `"select"` quando un elemento viene selezionato, ed un altro oggetto stare in ascolto dell'evento. E così via.
121121

122-
Here's the code:
122+
Qui vediamo il codice:
123123

124124
```js run
125125
let eventMixin = {
126126
/**
127-
* Subscribe to event, usage:
127+
* Iscrizione ad un evento, utilizzo:
128128
* menu.on('select', function(item) { ... }
129129
*/
130130
on(eventName, handler) {
@@ -136,7 +136,7 @@ let eventMixin = {
136136
},
137137

138138
/**
139-
* Cancel the subscription, usage:
139+
* Cancellare l'iscrizione, utilizzo:
140140
* menu.off('select', handler)
141141
*/
142142
off(eventName, handler) {
@@ -150,59 +150,59 @@ let eventMixin = {
150150
},
151151

152152
/**
153-
* Generate an event with the given name and data
153+
* Generare un evento con uno specifico nome ed i dati relativi
154154
* this.trigger('select', data1, data2);
155155
*/
156156
trigger(eventName, ...args) {
157157
if (!this._eventHandlers?.[eventName]) {
158-
return; // no handlers for that event name
158+
return; // nessun gestore per questo evento
159159
}
160160

161-
// call the handlers
161+
// invochiamo i gestori
162162
this._eventHandlers[eventName].forEach(handler => handler.apply(this, args));
163163
}
164164
};
165165
```
166166
167167
168-
- `.on(eventName, handler)` -- assigns function `handler` to run when the event with that name occurs. Technically, there's an `_eventHandlers` property that stores an array of handlers for each event name, and it just adds it to the list.
169-
- `.off(eventName, handler)` -- removes the function from the handlers list.
170-
- `.trigger(eventName, ...args)` -- generates the event: all handlers from `_eventHandlers[eventName]` are called, with a list of arguments `...args`.
168+
- `.on(eventName, handler)` -- assegna la funzione `handler` in modo tale che venga eseguita quando l'evento con il nome fornito viene generato. Tecnicamente, avremmo a disposizione anche la proprietà `_eventHandlers` che memorizza un array di gestori per ogni tipo di evento, quindi potremmo semplicemente aggiungerlo alla lista.
169+
- `.off(eventName, handler)` -- rimuove la funzione dalla lista dei gestori.
170+
- `.trigger(eventName, ...args)` -- genera l'evento: tutti i gestori in `_eventHandlers[eventName]` vengono invocati con la lista degli argomenti `...args`.
171171
172-
Usage:
172+
Utilizzo:
173173
174174
```js run
175-
// Make a class
175+
// Definiamo una classe
176176
class Menu {
177177
choose(value) {
178178
this.trigger("select", value);
179179
}
180180
}
181-
// Add the mixin with event-related methods
181+
// Aggiungiamo il mixin con i metodi relativi agli eventi
182182
Object.assign(Menu.prototype, eventMixin);
183183

184184
let menu = new Menu();
185185

186-
// add a handler, to be called on selection:
186+
// aggiungiamo un gestore, da invocare alla selezione:
187187
*!*
188188
menu.on("select", value => alert(`Value selected: ${value}`));
189189
*/!*
190190

191-
// triggers the event => the handler above runs and shows:
191+
// inneschiamo l'evento => il gestore definito sopra verrà invocato e mostrerà:
192192
// Value selected: 123
193193
menu.choose("123");
194194
```
195195
196-
Now, if we'd like any code to react to a menu selection, we can listen for it with `menu.on(...)`.
196+
Ora, nel caso volessimo che un'altra parte di codice reagisca alla selezione nel menu, ci basterà semplicemente aggiungere un listener con `menu.on(...)`.
197197
198-
And `eventMixin` mixin makes it easy to add such behavior to as many classes as we'd like, without interfering with the inheritance chain.
198+
E grazie al mixin `eventMixin`, questo comportamento diventa molto semplice da integrare in tutte le classi in cui desideriamo aggiungerlo, senza che questo vada ad interferire con l'ereditarietà.
199199
200-
## Summary
200+
## Riepilogo
201201
202-
*Mixin* -- is a generic object-oriented programming term: a class that contains methods for other classes.
202+
*Mixin* -- è un termine utilizzato nella programmazione orientata agli oggetti: un classe che contiene metodi utili per altre classi.
203203
204-
Some other languages allow multiple inheritance. JavaScript does not support multiple inheritance, but mixins can be implemented by copying methods into prototype.
204+
Molti altri linguaggi di programmazione consentono l'ereditarietà multipla. JavaScript non la supporta, ma possiamo implementare i mixin copiando i loro metodi all'interno del prototype.
205205
206-
We can use mixins as a way to augment a class by adding multiple behaviors, like event-handling as we have seen above.
206+
Possiamo utilizzare i mixins per migliorare una classe, andando ad aggiungere diversi comportamenti, come la gestione degli eventi vista sopra.
207207
208-
Mixins may become a point of conflict if they accidentally overwrite existing class methods. So generally one should think well about the naming methods of a mixin, to minimize the probability of that happening.
208+
I mixins potrebbero creare conflitti nel caso in cui andassero a sovrascrivere metodi già esistenti nella classe. Quindi, generalmente, i nomi dei metodi nei mixin vanno scelti con attenzione, in modo tale da minimizzare il rischio che si generino tali conflitti.

0 commit comments

Comments
 (0)