Skip to content

Commit 0b207b5

Browse files
authored
Merge pull request javascript-tutorial#382 from danilolmc/update-pt-mixins
Mixins
2 parents 887e731 + 787647e commit 0b207b5

File tree

2 files changed

+64
-67
lines changed

2 files changed

+64
-67
lines changed

1-js/09-classes/07-mixins/article.md

Lines changed: 59 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,51 @@
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+
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.
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+
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`;
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+
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.
88

9-
There's a concept that can help here, called "mixins".
9+
Existe um conceito que nos pode ajudar aqui, chamado "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+
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.
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+
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.
1414

15-
## A mixin example
15+
## Um exemplo de 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+
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.
1818

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

2121
```js run
2222
*!*
2323
// mixin
2424
*/!*
2525
let sayHiMixin = {
2626
sayHi() {
27-
alert(`Hello ${this.name}`);
27+
alert(`Olá ${this.name}`);
2828
},
2929
sayBye() {
30-
alert(`Bye ${this.name}`);
30+
alert(`Adeus ${this.name}`);
3131
}
32-
};
33-
3432
*!*
35-
// usage:
33+
// Utilização:
3634
*/!*
3735
class User {
3836
constructor(name) {
3937
this.name = name;
4038
}
4139
}
4240

43-
// copy the methods
41+
// copia os métodos
4442
Object.assign(User.prototype, sayHiMixin);
4543

46-
// now User can say hi
47-
new User("Dude").sayHi(); // Hello Dude!
44+
// agora User pode dizer oi
45+
new User("Dude").sayHi(); // Olá Dude!
4846
```
4947
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:
5149
5250
```js
5351
class User extends Person {
@@ -57,9 +55,9 @@ class User extends Person {
5755
Object.assign(User.prototype, sayHiMixin);
5856
```
5957
60-
Mixins can make use of inheritance inside themselves.
58+
Mixins podem usar herança dentro deles mesmos.
6159
62-
For instance, here `sayHiMixin` inherits from `sayMixin`:
60+
Por exemplo, aqui `sayHiMixin` herda de `sayMixin`:
6361
6462
```js run
6563
let sayMixin = {
@@ -69,16 +67,16 @@ let sayMixin = {
6967
};
7068

7169
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)
7371

7472
sayHi() {
7573
*!*
76-
// call parent method
74+
// chama o método pai
7775
*/!*
78-
super.say(`Hello ${this.name}`); // (*)
76+
super.say(`Olá ${this.name}`); // (*)
7977
},
8078
sayBye() {
81-
super.say(`Bye ${this.name}`); // (*)
79+
super.say(`Adeus ${this.name}`); // (*)
8280
}
8381
};
8482

@@ -87,44 +85,43 @@ class User {
8785
this.name = name;
8886
}
8987
}
90-
91-
// copy the methods
88+
// copia os métodos
9289
Object.assign(User.prototype, sayHiMixin);
9390

94-
// now User can say hi
95-
new User("Dude").sayHi(); // Hello Dude!
91+
// agora User pode dizer oi
92+
new User("Dude").sayHi(); // Olá Dude!
9693
```
9794
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.
9996
100-
Here's the diagram (see the right part):
97+
Aqui está o diagrama (veja a parte direita):
10198
10299
![](mixin-inheritance.svg)
103100
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.
105102
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]]`.
107104
108105
## EventMixin
109106
110-
Now let's make a mixin for real life.
107+
Vamos criar um mixin para a vida real.
111108
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.
113110
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`.
117114
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.
119116
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.
121118

122-
Here's the code:
119+
Aqui está o código:
123120

124121
```js run
125122
let eventMixin = {
126123
/**
127-
* Subscribe to event, usage:
124+
* Se inscreve ao evento, utilização:
128125
* menu.on('select', function(item) { ... }
129126
*/
130127
on(eventName, handler) {
@@ -136,7 +133,7 @@ let eventMixin = {
136133
},
137134
138135
/**
139-
* Cancel the subscription, usage:
136+
* Cancela a inscrição, utilização:
140137
* menu.off('select', handler)
141138
*/
142139
off(eventName, handler) {
@@ -150,59 +147,59 @@ let eventMixin = {
150147
},
151148
152149
/**
153-
* Generate an event with the given name and data
150+
* Gera um evento com o nome e dados providenciados
154151
* this.trigger('select', data1, data2);
155152
*/
156153
trigger(eventName, ...args) {
157154
if (!this._eventHandlers?.[eventName]) {
158-
return; // no handlers for that event name
155+
return; // sem manipuladores (handlers) para esse nome de evento
159156
}
160157
161-
// call the handlers
158+
// chama os manipuladores de eventos (handlers)
162159
this._eventHandlers[eventName].forEach(handler => handler.apply(this, args));
163160
}
164161
};
165162
```
166163

167164

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

172-
Usage:
169+
Utilização:
173170

174171
```js run
175-
// Make a class
172+
// Cria uma classe
176173
class Menu {
177174
choose(value) {
178175
this.trigger("select", value);
179176
}
180177
}
181-
// Add the mixin with event-related methods
178+
// Adiciona o mixin com os métodos relacionados aos eventos.
182179
Object.assign(Menu.prototype, eventMixin);
183180
184181
let menu = new Menu();
185182
186-
// add a handler, to be called on selection:
183+
// adiciona um manipulador de eventos, para ser chamado na seleção:
187184
*!*
188-
menu.on("select", value => alert(`Value selected: ${value}`));
185+
menu.on("select", value => alert(`Valor selecionado: ${value}`));
189186
*/!*
190187
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
193190
menu.choose("123");
194191
```
195192

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(...)`.
197194

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

200-
## Summary
197+
## Conclusão
201198

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

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. JavaScript não suporta herança múltipla, porém os mixins podem ser implementados copiando métodos para prototype.
205202

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

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.

1-js/09-classes/07-mixins/head.html

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
let eventMixin = {
33

44
/**
5-
* Subscribe to event, usage:
5+
* Se inscreve ao evento, utilização:
66
* menu.on('select', function(item) { ... }
77
*/
88
on(eventName, handler) {
@@ -14,7 +14,7 @@
1414
},
1515

1616
/**
17-
* Cancel the subscription, usage:
17+
* Cancela a inscrição, utilização:
1818
* menu.off('select', handler)
1919
*/
2020
off(eventName, handler) {
@@ -28,15 +28,15 @@
2828
},
2929

3030
/**
31-
* Generate the event and attach the data to it
31+
* Gera o evento e anexa os dados a ele
3232
* this.trigger('select', data1, data2);
3333
*/
3434
trigger(eventName, ...args) {
3535
if (!this._eventHandlers || !this._eventHandlers[eventName]) {
36-
return; // no handlers for that event name
36+
return; // // sem manipuladores (handlers) para esse nome de evento
3737
}
3838

39-
// call the handlers
39+
// chama o manipulador de eventos (handler)
4040
this._eventHandlers[eventName].forEach(handler => handler.apply(this, args));
4141
}
4242
};

0 commit comments

Comments
 (0)