Skip to content

Commit a5824b0

Browse files
authored
Merge pull request #271 from cortizg/es.javascript.info.1-09-07-m
Mixins
2 parents c8f6fc6 + f7ea2e4 commit a5824b0

File tree

2 files changed

+64
-64
lines changed

2 files changed

+64
-64
lines changed

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

Lines changed: 59 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,53 @@
1-
# Mixins
1+
# Los 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+
En JavaScript podemos heredar de un solo objeto. Solo puede haber un `[[Prototype]]` para un objeto. Y una clase puede extender únicamente otra clase.
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+
Pero a veces eso se siente restrictivo. Por ejemplo, tenemos una clase `StreetSweeper` y una clase `Bicycle`, y queremos hacer su combinación: 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+
O tenemos una clase `User` y una clase `EventEmitter` que implementa la generación de eventos, y nos gustaría agregar la funcionalidad de `EventEmitter` a `User`, para que nuestros usuarios puedan emitir eventos.
88

9-
There's a concept that can help here, called "mixins".
9+
Hay un concepto que puede ayudar aquí, llamado "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 se define en Wikipedia, un [mixin](https://es.wikipedia.org/wiki/Mixin) es una clase que contiene métodos que pueden ser utilizados por otras clases sin necesidad de heredar de ella.
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+
En otras palabras, un *mixin* proporciona métodos que implementan cierto comportamiento, pero su uso no es exclusivo, lo usamos para agregar el comportamiento a otras clases.
1414

15-
## A mixin example
15+
## Un ejemplo 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+
La forma más sencilla de implementar un mixin en JavaScript es hacer un objeto con métodos útiles, para que podamos combinarlos fácilmente en un prototipo de cualquier clase.
1818

19-
For instance here the mixin `sayHiMixin` is used to add some "speech" for `User`:
19+
Por ejemplo, aquí el mixin `sayHiMixin` se usa para agregar algo de "diálogo" a `User`:
2020

2121
```js run
2222
*!*
2323
// mixin
2424
*/!*
2525
let sayHiMixin = {
2626
sayHi() {
27-
alert(`Hello ${this.name}`);
27+
alert(`Hola ${this.name}`);
2828
},
2929
sayBye() {
30-
alert(`Bye ${this.name}`);
30+
alert(`Adios ${this.name}`);
3131
}
3232
};
3333

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

43-
// copy the methods
43+
// copia los métodos
4444
Object.assign(User.prototype, sayHiMixin);
4545

46-
// now User can say hi
47-
new User("Dude").sayHi(); // Hello Dude!
46+
// Ahora el User puede decir hola
47+
new User("tío").sayHi(); // Hola tío!
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+
No hay herencia, sino un simple método de copia. Entonces, `User` puede heredar de otra clase y también incluir el mixin para "mezclar" los métodos adicionales, como este:
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+
Los mixins pueden hacer uso de la herencia dentro de sí mismos.
6161

62-
For instance, here `sayHiMixin` inherits from `sayMixin`:
62+
Por ejemplo, aquí `sayHiMixin` hereda de `sayMixin`:
6363

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

7171
let sayHiMixin = {
72-
__proto__: sayMixin, // (or we could use Object.create to set the prototype here)
72+
__proto__: sayMixin, // (o podríamos usar Object.create para configurar el prototype aquí)
7373

7474
sayHi() {
7575
*!*
76-
// call parent method
76+
// llama al método padre
7777
*/!*
78-
super.say(`Hello ${this.name}`); // (*)
78+
super.say(`Hola ${this.name}`); // (*)
7979
},
8080
sayBye() {
81-
super.say(`Bye ${this.name}`); // (*)
81+
super.say(`Adios ${this.name}`); // (*)
8282
}
8383
};
8484

@@ -88,43 +88,43 @@ class User {
8888
}
8989
}
9090

91-
// copy the methods
91+
// copia los métodos
9292
Object.assign(User.prototype, sayHiMixin);
9393

94-
// now User can say hi
95-
new User("Dude").sayHi(); // Hello Dude!
94+
// User ahora puede decir hola
95+
new User("tío").sayHi(); // Hola tío!
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+
Ten en cuenta que la llamada al método padre `super.say()` de `sayHiMixin` (en las líneas etiquetadas con `(*)`) busca el método en el prototipo de ese mixin, no en la clase.
9999

100-
Here's the diagram (see the right part):
100+
Aquí está el diagrama (ver la parte derecha):
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+
Esto se debe a que los métodos `sayHi` y `sayBye` se crearon inicialmente en `sayHiMixin`. Entonces, a pesar de que se copiaron, su propiedad interna `[[[HomeObject]]` hace referencia a `sayHiMixin`, como se muestra en la imagen de arriba.
105105

106-
As `super` looks for parent methods in `[[HomeObject]].[[Prototype]]`, that means it searches `sayHiMixin.[[Prototype]]`, not `User.[[Prototype]]`.
106+
Como `super` busca métodos primarios en `[[HomeObject]].[[Prototype]]`, significa que busca `sayHiMixin.[[Prototype]]`, no `User.[[Prototype]]`.
107107

108108
## EventMixin
109109

110-
Now let's make a mixin for real life.
110+
Ahora hagamos un mixin para la vida real.
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 característica importante de muchos objetos del navegador (por ejemplo) es que pueden generar eventos. Los eventos son una excelente manera de "transmitir información" a cualquiera que lo desee. Así que hagamos un mixin que nos permita agregar fácilmente funciones relacionadas con eventos a cualquier clase/objeto.
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+
- El mixin proporcionará un método `.trigger(name, [...data])` para "generar un evento" cuando le ocurra algo importante. El argumento `name` es un nombre del evento, opcionalmente seguido de argumentos adicionales con datos del evento.
115+
- También el método `.on(name, handler)` que agrega la función `handler` como listener a eventos con el nombre dado. Se llamará cuando se desencadene un evento con el nombre `name` dado, y obtenga los argumentos de la llamada `.trigger`.
116+
- ...Y el método `.off(name, handler)` que elimina el 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+
Después de agregar el mixin, un objeto `user` podrá generar un evento `"login"` cuando el visitante inicie sesión. Y otro objeto, por ejemplo, `calendar` puede querer escuchar dichos eventos para cargar el calendario para el persona registrada.
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+
O bien, un `menu` puede generar el evento `"seleccionar"` cuando se selecciona un elemento del menú, y otros objetos pueden asignar controladores para reaccionar ante ese evento. Y así.
121121

122-
Here's the code:
122+
Aquí está el código:
123123

124124
```js run
125125
let eventMixin = {
126126
/**
127-
* Subscribe to event, usage:
127+
* Suscribe al evento, uso:
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+
* Cancelar la suscripción, uso:
140140
* menu.off('select', handler)
141141
*/
142142
off(eventName, handler) {
@@ -150,12 +150,12 @@ let eventMixin = {
150150
},
151151

152152
/**
153-
* Generate an event with the given name and data
153+
* Generar un evento con el nombre y los datos
154154
* this.trigger('select', data1, data2);
155155
*/
156156
trigger(eventName, ...args) {
157157
if (!this._eventHandlers || !this._eventHandlers[eventName]) {
158-
return; // no handlers for that event name
158+
return; // no hay controladores para ese nombre de evento
159159
}
160160

161161
// call the handlers
@@ -165,44 +165,44 @@ let eventMixin = {
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)`: asigna la función `handler` para que se ejecute cuando se produce el evento con ese nombre. Técnicamente, hay una propiedad `_eventHandlers` que almacena una matriz de controladores para cada nombre de evento, y simplemente la agrega a la lista.
169+
- `.off(eventName, handler)` - elimina la función de la lista de controladores.
170+
- `.trigger(eventName, ...args)` - genera el evento: se llama a todos los controladores de `_eventHandlers[eventName]`, con una lista de argumentos `...args`.
171171
172-
Usage:
172+
Uso:
173173
174174
```js run
175-
// Make a class
175+
// Construir una clase
176176
class Menu {
177177
choose(value) {
178178
this.trigger("select", value);
179179
}
180180
}
181-
// Add the mixin with event-related methods
181+
// Agrega el mixin con métodos relacionados con eventos
182182
Object.assign(Menu.prototype, eventMixin);
183183

184184
let menu = new Menu();
185185

186-
// add a handler, to be called on selection:
186+
// agrega un controlador, que se llamará en la selección:
187187
*!*
188-
menu.on("select", value => alert(`Value selected: ${value}`));
188+
menu.on("select", value => alert(`Valor seleccionado: ${value}`));
189189
*/!*
190190

191-
// triggers the event => the handler above runs and shows:
192-
// Value selected: 123
191+
// desencadena el evento => el controlador anterior se ejecuta y muestra:
192+
// Valor seleccionado: 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+
Ahora, si queremos que el código reaccione a una selección de menú, podemos escucharlo 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+
Y el mixin de `eventMixin` hace que sea fácil agregar ese comportamiento a tantas clases como queramos, sin interferir con la cadena de herencia.
199199
200-
## Summary
200+
## Resumen
201201
202-
*Mixin* -- is a generic object-oriented programming term: a class that contains methods for other classes.
202+
*Mixin* -- es un término genérico de programación orientado a objetos: una clase que contiene métodos para otras clases.
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+
Algunos lenguajes permiten la herencia múltiple. JavaScript no admite la herencia múltiple, pero los mixins se pueden implementar copiando métodos en el prototipo.
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+
Podemos usar mixins como una forma de expandir una clase agregando múltiples comportamientos, como el manejo de eventos que hemos visto anteriormente.
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+
Los mixins pueden convertirse en un punto de conflicto si sobrescriben accidentalmente los métodos de clase existentes. Por lo tanto, generalmente debes planificar correctamente la definición de métodos de un mixin, para minimizar la probabilidad de que suceda.

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+
* Suscríbete al evento, uso:
66
* menu.on('select', function(item) { ... }
77
*/
88
on(eventName, handler) {
@@ -14,7 +14,7 @@
1414
},
1515

1616
/**
17-
* Cancel the subscription, usage:
17+
* Cancelar la suscripción, uso:
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+
* Genere el evento y adjúntele los datos.
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; // no hay controladores para ese nombre de evento
3737
}
3838

39-
// call the handlers
39+
// llama a los manejadores
4040
this._eventHandlers[eventName].forEach(handler => handler.apply(this, args));
4141
}
4242
};

0 commit comments

Comments
 (0)