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
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
+
Em JavaScript, só se pode herdar de um único objeto. Pode apenas existir um único`[[Prototype]]`para um objeto. E uma classe pode estender apenas uma outra classe.
4
4
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
+
Porém, algumas vezes isso parece limitante. Por exemplo, temos uma classe `StreetSweeper`e uma classe`Bicycle`, e queremos fazer uma mistura delas: uma classe `StreetSweepingBicycle`;
6
6
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
+
Ou temos uma classe `User`e uma classe`EventEmitter`que implementa a geração de eventos, e gostaríamos de adicionar a funcionalidade de `EventEmitter`à`User`, para que nossos usuários possam emitir eventos.
8
8
9
-
There's a concept that can help here, called "mixins".
9
+
Existe um conceito que nos pode ajudar aqui, chamado "mixins".
10
10
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
+
Como definido no Wikipedia, um[mixin](https://en.wikipedia.org/wiki/Mixin)é uma classe contendo métodos que podem ser usados por outras classes sem a necessidade de herdar dela.
12
12
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
+
Em outras palavras, um*mixin*fornece métodos que implementam um determinado comportamento, mas não é utilizado sozinho, nós o utilizamos para adicionar o comportamento a outras classes.
14
14
15
-
## A mixin example
15
+
## Um exemplo de mixin
16
16
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
+
A maneira mais simples de implementar um mixin em JavaScript é criando um objeto com métodos úteis, para que possamos facilmente mesclá-los em um prototype de outra classe.
18
18
19
-
For instance here the mixin `sayHiMixin`is used to add some "speech" for`User`:
19
+
Por exemplo, aqui o mixin `sayHiMixin`é usado para adicionar alguma "fala" para`User`:
20
20
21
21
```js run
22
22
*!*
23
23
// mixin
24
24
*/!*
25
25
let sayHiMixin = {
26
26
sayHi() {
27
-
alert(`Hello${this.name}`);
27
+
alert(`Olá${this.name}`);
28
28
},
29
29
sayBye() {
30
-
alert(`Bye${this.name}`);
30
+
alert(`Adeus${this.name}`);
31
31
}
32
-
};
33
-
34
32
*!*
35
-
//usage:
33
+
//Utilização:
36
34
*/!*
37
35
classUser {
38
36
constructor(name) {
39
37
this.name= name;
40
38
}
41
39
}
42
40
43
-
//copy the methods
41
+
//copia os métodos
44
42
Object.assign(User.prototype, sayHiMixin);
45
43
46
-
//now User can say hi
47
-
newUser("Dude").sayHi(); //Hello Dude!
44
+
//agora User pode dizer oi
45
+
newUser("Dude").sayHi(); //Olá Dude!
48
46
```
49
47
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:
48
+
Não existe herança, mas uma simples cópia de métodos. Portanto,`User`pode herdar de outra classe e também incluir o mixin para "misturar" (mix-in) os métodos adicionais, assim:
51
49
52
50
```js
53
51
classUserextendsPerson {
@@ -57,9 +55,9 @@ class User extends Person {
57
55
Object.assign(User.prototype, sayHiMixin);
58
56
```
59
57
60
-
Mixins can make use of inheritance inside themselves.
58
+
Mixins podem usar herança dentro deles mesmos.
61
59
62
-
For instance, here`sayHiMixin`inherits from`sayMixin`:
60
+
Por exemplo, aqui`sayHiMixin`herda de`sayMixin`:
63
61
64
62
```js run
65
63
let sayMixin = {
@@ -69,16 +67,16 @@ let sayMixin = {
69
67
};
70
68
71
69
let sayHiMixin = {
72
-
__proto__: sayMixin, // (or we could use Object.setPrototypeOf to set the prototype here)
70
+
__proto__: sayMixin, // (ou poderíamos usar Object.setPrototypeOf para definir o prototype aqui)
73
71
74
72
sayHi() {
75
73
*!*
76
-
//call parent method
74
+
//chama o método pai
77
75
*/!*
78
-
super.say(`Hello${this.name}`); // (*)
76
+
super.say(`Olá${this.name}`); // (*)
79
77
},
80
78
sayBye() {
81
-
super.say(`Bye${this.name}`); // (*)
79
+
super.say(`Adeus${this.name}`); // (*)
82
80
}
83
81
};
84
82
@@ -87,44 +85,43 @@ class User {
87
85
this.name= name;
88
86
}
89
87
}
90
-
91
-
// copy the methods
88
+
// copia os métodos
92
89
Object.assign(User.prototype, sayHiMixin);
93
90
94
-
//now User can say hi
95
-
newUser("Dude").sayHi(); //Hello Dude!
91
+
//agora User pode dizer oi
92
+
newUser("Dude").sayHi(); //Olá Dude!
96
93
```
97
94
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.
95
+
Observe que a chamada do método pai `super.say()`por`sayHiMixin` (nas linhas marcadas com`(*)`) procura pelo método no prototype desse mixin, não na classe.
99
96
100
-
Here's the diagram (see the right part):
97
+
Aqui está o diagrama (veja a parte direita):
101
98
102
99

103
100
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.
101
+
Isso porque os métodos `sayHi`e`sayBye`foram inicialmente criados em`sayHiMixin`. Portanto, mesmo que tenham sido copiados, suas propriedades internas `[[HomeObject]]`referenciam a `sayHiMixin`, como mostrado na figura acima.
105
102
106
-
As`super`looks for parent methods in`[[HomeObject]].[[Prototype]]`, that means it searches`sayHiMixin.[[Prototype]]`.
103
+
Como`super`procura por métodos pais em`[[HomeObject]].[[Prototype]]`, isso significa que procura em`sayHiMixin.[[Prototype]]`.
107
104
108
105
## EventMixin
109
106
110
-
Now let's make a mixin for real life.
107
+
Vamos criar um mixin para a vida real.
111
108
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.
109
+
Uma característica importante de muitos objetos do navegador (por exemplo) é que eles podem gerar eventos. Eventos são uma ótima maneira de "transmitir informação" para qualquer um que a quiser. Então, vamos criar um mixin que nos permita facilmente adicionar funções relacionadas a eventos a qualquer classe/objeto.
113
110
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.
111
+
- O mixin vai fornecer um método`.trigger(name, [...data])`para "gerar um evento" quando algo importante acontecer com ele. O argumento `name`é o nome do evento, e é opcionalmente seguido de argumentos provendo dados do evento.
112
+
- E também o método `.on(name, handler)`que adiciona a função `handler`como ouvinte de eventos com o dado nome. Ela será chamada quando um evento com o dado `name`disparar, e irá obter os argumentos da chamada de `.trigger`
113
+
- ...E o método`.off(name, handler)`que remove o ouvinte `handler`.
117
114
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.
115
+
Após adicionar o mixin, um objeto`user`será capaz de gerar um evento `"login"`quando o visitante fizer login. Um outro objeto, digamos, `calendar`pode querer ouvir por tais eventos para carregar o calendário para a pessoa logada.
119
116
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.
117
+
Ou, um`menu`pode gerar o evento`"select"`quando um item do menu for selecionado`, e outros objetos podem atribuir manipuladores (handlers) para reagir àquele evento. E assim por diante.
121
118
122
-
Here's the code:
119
+
Aqui está o código:
123
120
124
121
```js run
125
122
let eventMixin = {
126
123
/**
127
-
* Subscribe to event, usage:
124
+
* Se inscreve ao evento, utilização:
128
125
* menu.on('select', function(item) { ... }
129
126
*/
130
127
on(eventName, handler) {
@@ -136,7 +133,7 @@ let eventMixin = {
136
133
},
137
134
138
135
/**
139
-
* Cancel the subscription, usage:
136
+
* Cancela a inscrição, utilização:
140
137
* menu.off('select', handler)
141
138
*/
142
139
off(eventName, handler) {
@@ -150,59 +147,59 @@ let eventMixin = {
150
147
},
151
148
152
149
/**
153
-
* Generate an event with the given name and data
150
+
* Gera um evento com o nome e dados providenciados
154
151
* this.trigger('select', data1, data2);
155
152
*/
156
153
trigger(eventName, ...args) {
157
154
if (!this._eventHandlers?.[eventName]) {
158
-
return; //no handlers for that event name
155
+
return; // sem manipuladores (handlers) para esse nome de evento
- `.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`.
165
+
-`.on(eventName, handler)`--atribui a função `handler`para ser executada quando o evento com aquele nome ocorre. Tecnicamente, existe uma propriedade `_eventHandlers`que armazena um array de manipuladores de evento para cada nome de evento, e o método apenas adiciona o manipulador à lista.
166
+
-`.off(eventName, handler)`--remove a função da lista de manipuladores de evento.
167
+
-`.trigger(eventName, ...args)`--gera o evento: todos os manipuladores de eventos de `_eventHandlers[eventName]`são chamados, com a lista de argumentos`...args`.
171
168
172
-
Usage:
169
+
Utilização:
173
170
174
171
```js run
175
-
//Make a class
172
+
// Cria uma classe
176
173
class Menu {
177
174
choose(value) {
178
175
this.trigger("select", value);
179
176
}
180
177
}
181
-
//Add the mixin with event-related methods
178
+
// Adiciona o mixin com os métodos relacionados aos eventos.
182
179
Object.assign(Menu.prototype, eventMixin);
183
180
184
181
let menu = new Menu();
185
182
186
-
//add a handler, to be called on selection:
183
+
// adiciona um manipulador de eventos, para ser chamado na seleção:
menu.on("select", value => alert(`Valor selecionado: ${value}`));
189
186
*/!*
190
187
191
-
//triggers the event => the handler above runs and shows:
192
-
//Value selected: 123
188
+
// dispara o evento => o manipulador de evento acima é executado e mostra:
189
+
// Valor selecionado: 123
193
190
menu.choose("123");
194
191
```
195
192
196
-
Now, if we'd like any code to react to a menu selection, we can listen for it with`menu.on(...)`.
193
+
Agora, se quisermos que qualquer código reaja a uma seleção do menu, podemos ouvir com`menu.on(...)`.
197
194
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.
195
+
E o mixin `eventMixin`facilita a adição do tal comportamento para tantas classes quanto quisermos, sem interferir na cadeia de herança.
199
196
200
-
## Summary
197
+
## Conclusão
201
198
202
-
*Mixin* -- is a generic object-oriented programming term: a class that contains methods for other classes.
199
+
*Mixin*--é um termo genérico de programação orientada a objetos: uma classe que contém métodos para outras classes.
203
200
204
-
Some other languages allow multiple inheritance. JavaScript does not support multiple inheritance, but mixins can be implemented by copying methods into prototype.
201
+
Algumas outras linguagens permitem herança múltipla. JavaScriptnão suporta herança múltipla, porém os mixins podem ser implementados copiando métodos para prototype.
205
202
206
-
We can use mixins as a way to augment a class by adding multiple behaviors, like event-handling as we have seen above.
203
+
Podemos usar mixins como uma maneira de incrementar uma classe adicionando múltiplos comportamentos, como manipulação de eventos como vimos acima.
207
204
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.
205
+
Mixins podem se tornar num ponto de conflito se eles acidentalmente sobrescreverem métodos existentes na classe. Então geralmente deve-se pensar bem sobre a nomenclatura dos métodos de um mixin, para minimizar a probabilidade disso acontecer.
0 commit comments