From b35438e32831c0f739422b6fcb1f40f452186444 Mon Sep 17 00:00:00 2001 From: Carlos Ortiz Gutierrez Date: Sat, 9 May 2020 19:09:40 -0600 Subject: [PATCH 1/6] 1-09-06 Traducido 5 --- .../1-strange-instanceof/solution.md | 8 +- .../1-strange-instanceof/task.md | 6 +- 1-js/09-classes/06-instanceof/article.md | 155 +++++++++--------- 1-js/09-classes/06-instanceof/instanceof.svg | 52 +----- 4 files changed, 89 insertions(+), 132 deletions(-) diff --git a/1-js/09-classes/06-instanceof/1-strange-instanceof/solution.md b/1-js/09-classes/06-instanceof/1-strange-instanceof/solution.md index d41d90edf..80884f7b3 100644 --- a/1-js/09-classes/06-instanceof/1-strange-instanceof/solution.md +++ b/1-js/09-classes/06-instanceof/1-strange-instanceof/solution.md @@ -1,7 +1,7 @@ -Yeah, looks strange indeed. +Sí, se ve extraño de hecho. -But `instanceof` does not care about the function, but rather about its `prototype`, that it matches against the prototype chain. +Pero a `instanceof` no le importa la función, sino más bien su `prototype`, que coincide con la cadena del prototipo. -And here `a.__proto__ == B.prototype`, so `instanceof` returns `true`. +Y aquí `a.__ proto__ == B.prototype`, entonces `instanceof` devuelve `true`. -So, by the logic of `instanceof`, the `prototype` actually defines the type, not the constructor function. +Entonces, según la lógica de `instanceof`, el `prototype` en realidad define el tipo, no la función constructora. diff --git a/1-js/09-classes/06-instanceof/1-strange-instanceof/task.md b/1-js/09-classes/06-instanceof/1-strange-instanceof/task.md index e9481912a..07bb311a4 100644 --- a/1-js/09-classes/06-instanceof/1-strange-instanceof/task.md +++ b/1-js/09-classes/06-instanceof/1-strange-instanceof/task.md @@ -2,9 +2,9 @@ importance: 5 --- -# Strange instanceof +# Extraño instanceof -Why `instanceof` below returns `true`? We can easily see that `a` is not created by `B()`. +En el siguiente código, ¿por qué `instanceof` devuelve `true`? Podemos ver fácilmente que `a` no es creado por `B()`. ```js run function A() {} @@ -15,6 +15,6 @@ A.prototype = B.prototype = {}; let a = new A(); *!* -alert( a instanceof B ); // true +alert( a instanceof B ); // verdadero */!* ``` diff --git a/1-js/09-classes/06-instanceof/article.md b/1-js/09-classes/06-instanceof/article.md index e7800535d..4bc9f8767 100644 --- a/1-js/09-classes/06-instanceof/article.md +++ b/1-js/09-classes/06-instanceof/article.md @@ -1,59 +1,62 @@ -# Class checking: "instanceof" +# Comprobación de clase: "instanceof" -The `instanceof` operator allows to check whether an object belongs to a certain class. It also takes inheritance into account. +El operador `instanceof` permite verificar si un objeto pertenece a una clase determinada. También tiene en cuenta la herencia. -Such a check may be necessary in many cases, here we'll use it for building a *polymorphic* function, the one that treats arguments differently depending on their type. +Tal verificación puede ser necesaria en muchos casos. Aquí lo usaremos para construir una función *polimórfica*, la que trata los argumentos de manera diferente dependiendo de su tipo. -## The instanceof operator [#ref-instanceof] +## El operador instanceof [#ref-instanceof] -The syntax is: +La sintaxis es: ```js obj instanceof Class ``` -It returns `true` if `obj` belongs to the `Class` (or a class inheriting from it). +Devuelve `true` si `obj` pertenece a la `Class` o una clase que hereda de ella. -For instance: +Por ejemplo: ```js run class Rabbit {} let rabbit = new Rabbit(); -// is it an object of Rabbit class? +// ¿Es un objeto de la clase Rabbit? *!* -alert( rabbit instanceof Rabbit ); // true +alert( rabbit instanceof Rabbit ); // verdadero */!* ``` -It also works with constructor functions: +También funciona con funciones de constructor: ```js run *!* -// instead of class +// en lugar de clase function Rabbit() {} */!* -alert( new Rabbit() instanceof Rabbit ); // true +alert( new Rabbit() instanceof Rabbit ); // verdadero ``` -...And with built-in classes like `Array`: +...Y con clases integradas como `Array`: ```js run let arr = [1, 2, 3]; -alert( arr instanceof Array ); // true -alert( arr instanceof Object ); // true +alert( arr instanceof Array ); // verdadero +alert( arr instanceof Object ); // verdadero ``` -Please note that `arr` also belongs to the `Object` class. That's because `Array` prototypally inherits from `Object`. +Tenga en cuenta que `arr` también pertenece a la clase `Object`. Esto se debe a que `Array` hereda prototípicamente de `Object`. -The `instanceof` operator examines the prototype chain for the check, and is also fine-tunable using the static method `Symbol.hasInstance`. +Normalmente, `instanceof` examina la cadena de prototipos para la verificación. También podemos establecer una lógica personalizada en el método estático `Symbol.hasInstance`. -The algorithm of `obj instanceof Class` works roughly as follows: +El algoritmo de `obj instanceof Class` funciona más o menos de la siguiente manera: -1. If there's a static method `Symbol.hasInstance`, then use it. Like this: +1. Si hay un método estático `Symbol.hasInstance`, simplemente llámelo: `Class[Symbol.hasInstance](obj)`. Debería devolver `true` o `false`, y hemos terminado. Así es como podemos personalizar el comportamiento de `instanceof`. + + Por ejemplo: ```js run - // assume anything that canEat is an animal + // Instalar instancia de verificación que asume que + // cualquier cosa con propiedad canEat es un animal class Animal { static [Symbol.hasInstance](obj) { if (obj.canEat) return true; @@ -61,22 +64,25 @@ The algorithm of `obj instanceof Class` works roughly as follows: } let obj = { canEat: true }; - alert(obj instanceof Animal); // true: Animal[Symbol.hasInstance](obj) is called + + alert(obj instanceof Animal); // verdadero: Animal[Symbol.hasInstance](obj) es llamadoda ``` -2. Most classes do not have `Symbol.hasInstance`. In that case, check if `Class.prototype` equals to one of prototypes in the `obj` prototype chain. +2. La mayoría de las clases no tienen `Symbol.hasInstance`. En ese caso, se utiliza la lógica estándar: `obj instanceOf Class` comprueba si `Class.prototype` es igual a uno de los prototipos en la cadena de prototipos `obj`. - In other words, compare: + En otras palabras, compara uno tras otro: ```js - obj.__proto__ === Class.prototype - obj.__proto__.__proto__ === Class.prototype - obj.__proto__.__proto__.__proto__ === Class.prototype + obj.__proto__ === Class.prototype? + obj.__proto__.__proto__ === Class.prototype? + obj.__proto__.__proto__.__proto__ === Class.prototype? ... + // si alguna respuesta es verdadera, devuelve true + // de lo contrario, si llegamos al final de la cadena, devuelve false ``` - In the example above `Rabbit.prototype === rabbit.__proto__`, so that gives the answer immediately. + En el ejemplo anterior `rabbit.__ proto__ === Rabbit.prototype`, por lo que da la respuesta de inmediato. - In the case of an inheritance, `rabbit` is an instance of the parent class as well: + En el caso de una herencia, la coincidencia será en el segundo paso: ```js run class Animal {} @@ -84,78 +90,79 @@ The algorithm of `obj instanceof Class` works roughly as follows: let rabbit = new Rabbit(); *!* - alert(rabbit instanceof Animal); // true + alert(rabbit instanceof Animal); // verdadero */!* + // rabbit.__proto__ === Rabbit.prototype - // rabbit.__proto__.__proto__ === Animal.prototype (match!) + *!* + // rabbit.__proto__.__proto__ === Animal.prototype (iguala!) + */!* ``` -Here's the illustration of what `rabbit instanceof Animal` compares with `Animal.prototype`: +Aquí está la ilustración de lo que `rabbit instanceof Animal` compara con `Animal.prototype`: ![](instanceof.svg) -By the way, there's also a method [objA.isPrototypeOf(objB)](mdn:js/object/isPrototypeOf), that returns `true` if `objA` is somewhere in the chain of prototypes for `objB`. So the test of `obj instanceof Class` can be rephrased as `Class.prototype.isPrototypeOf(obj)`. +Por cierto, también hay un método [objA.isPrototypeOf(objB)] (mdn:js/object/isPrototypeOf), que devuelve `true` si `objA` está en algún lugar de la cadena de prototipos para `objB`. Por lo tanto, la prueba de `obj instanceof Class` se puede reformular como `Class.prototype.isPrototypeOf(obj)`. -That's funny, but the `Class` constructor itself does not participate in the check! Only the chain of prototypes and `Class.prototype` matters. +Es divertido, ¡pero el constructor `Class` en sí mismo no participa en el chequeo! Solo importa la cadena de prototipos y `Class.prototype`. -That can lead to interesting consequences when `prototype` is changed. +Eso puede llevar a consecuencias interesantes cuando se cambia una propiedad `prototype` después de crear el objeto. -Like here: +Como aquí: ```js run function Rabbit() {} let rabbit = new Rabbit(); -// changed the prototype +// cambió el prototipo Rabbit.prototype = {}; -// ...not a rabbit any more! +// ...ya no es un conejo! *!* -alert( rabbit instanceof Rabbit ); // false +alert( rabbit instanceof Rabbit ); // falso */!* ``` -That's one of the reasons to avoid changing `prototype`. Just to keep safe. - -## Bonus: Object toString for the type +## Bonificación: Object.prototype.toString para el tipo -We already know that plain objects are converted to string as `[object Object]`: +Ya sabemos que los objetos simples se convierten en cadenas como `[objetc Objetc]`: ```js run let obj = {}; alert(obj); // [object Object] -alert(obj.toString()); // the same +alert(obj.toString()); // lo mismo ``` -That's their implementation of `toString`. But there's a hidden feature that makes `toString` actually much more powerful than that. We can use it as an extended `typeof` and an alternative for `instanceof`. +Esa es su implementación de `toString`. Pero hay una característica oculta que hace que `toString` sea mucho más poderoso que eso. Podemos usarlo como un `typeof` extendido y una alternativa para `instanceof`. -Sounds strange? Indeed. Let's demystify. +¿Suena extraño? En efecto. Vamos a desmitificar. -By [specification](https://tc39.github.io/ecma262/#sec-object.prototype.tostring), the built-in `toString` can be extracted from the object and executed in the context of any other value. And its result depends on that value. +Mediante [especificación](https://tc39.github.io/ecma262/#sec-object.prototype.tostring), el `toString` incorporado puede extraerse del objeto y ejecutarse en el contexto de cualquier otro valor. Y su resultado depende de ese valor. -- For a number, it will be `[object Number]` -- For a boolean, it will be `[object Boolean]` -- For `null`: `[object Null]` -- For `undefined`: `[object Undefined]` -- For arrays: `[object Array]` -- ...etc (customizable). +- Para un número, será `[object Number]` +- Para un booleano, será `[objetc Boolean]` +- Para `null`: `[objetc Null]` +- Para `undefined`: `[objetc Undefined]` +- Para matrices: `[Object Array]` +- ... etc (personalizable). -Let's demonstrate: +Demostremos: ```js run -// copy toString method into a variable for convenience +// copie el método toString en una variable a conveniencia let objectToString = Object.prototype.toString; -// what type is this? +// ¿que tipo es este? let arr = []; -alert( objectToString.call(arr) ); // [object Array] +alert( objectToString.call(arr) ); // [object *!*Array*/!*] ``` -Here we used [call](mdn:js/function/call) as described in the chapter [](info:call-apply-decorators) to execute the function `objectToString` in the context `this=arr`. +Aquí usamos [call](mdn:js/function/call) como se describe en el capítulo [](info:call-apply-decorators) para ejecutar la función `objectToString` en el contexto `this=arr`. -Internally, the `toString` algorithm examines `this` and returns the corresponding result. More examples: +Internamente, el algoritmo `toString` examina `this` y devuelve el resultado correspondiente. Más ejemplos: ```js run let s = Object.prototype.toString; @@ -167,9 +174,9 @@ alert( s.call(alert) ); // [object Function] ### Symbol.toStringTag -The behavior of Object `toString` can be customized using a special object property `Symbol.toStringTag`. +El comportamiento del objeto `toString` se puede personalizar utilizando una propiedad de objeto especial `Symbol.toStringTag`. -For instance: +Por ejemplo: ```js run let user = { @@ -179,33 +186,33 @@ let user = { alert( {}.toString.call(user) ); // [object User] ``` -For most environment-specific objects, there is such a property. Here are few browser specific examples: +Para la mayoría de los objetos específicos del entorno, existe dicha propiedad. Aquí hay algunos ejemplos específicos del navegador: ```js run -// toStringTag for the envinronment-specific object and class: -alert( window[Symbol.toStringTag]); // window +// ttoStringTag para el objeto y clase específicos del entorno: +alert( window[Symbol.toStringTag]); // ventana alert( XMLHttpRequest.prototype[Symbol.toStringTag] ); // XMLHttpRequest alert( {}.toString.call(window) ); // [object Window] alert( {}.toString.call(new XMLHttpRequest()) ); // [object XMLHttpRequest] ``` -As you can see, the result is exactly `Symbol.toStringTag` (if exists), wrapped into `[object ...]`. +Como puedes ver, el resultado es exactamente `Symbol.toStringTag` (si existe), envuelto en `[objetc ...]`. -At the end we have "typeof on steroids" that not only works for primitive data types, but also for built-in objects and even can be customized. +Al final tenemos "typeof con esteroides" que no solo funciona para tipos de datos primitivos, sino también para objetos incorporados e incluso puede personalizarse. -It can be used instead of `instanceof` for built-in objects when we want to get the type as a string rather than just to check. +Podemos usar `{}.toString.call` en lugar de `instanceof` para los objetos incorporados cuando deseamos obtener el tipo como una cadena en lugar de solo verificar. -## Summary +## Resumen -Let's recap the type-checking methods that we know: +Resumamos los métodos de verificación de tipos que conocemos: -| | works for | returns | +| | trabaja para | retorna | |---------------|-------------|---------------| -| `typeof` | primitives | string | -| `{}.toString` | primitives, built-in objects, objects with `Symbol.toStringTag` | string | -| `instanceof` | objects | true/false | +| `typeof` | primitivos | cadena | +| `{}.toString` | primitivos, objetos incorporados, objetos con `Symbol.toStringTag` | cadena | +| `instanceof` | objetos | true/false | -As we can see, `{}.toString` is technically a "more advanced" `typeof`. +Como podemos ver, `{}.toString` es técnicamente un `typeof` "más avanzado". -And `instanceof` operator really shines when we are working with a class hierarchy and want to check for the class taking into account inheritance. +Y el operador `instanceof` realmente brilla cuando estamos trabajando con una jerarquía de clases y queremos verificar si la clase tiene en cuenta la herencia. diff --git a/1-js/09-classes/06-instanceof/instanceof.svg b/1-js/09-classes/06-instanceof/instanceof.svg index b291384f2..78bff9f12 100644 --- a/1-js/09-classes/06-instanceof/instanceof.svg +++ b/1-js/09-classes/06-instanceof/instanceof.svg @@ -1,51 +1 @@ - - - - instanceof.svg - Created with sketchtool. - - - - - Animal.prototype - - - - Object.prototype - - - - - Rabbit.prototype - - - - [[Prototype]] - - - - rabbit - - - - [[Prototype]] - - - [[Prototype]] - - - - null - - - [[Prototype]] - - - = Animal.prototype? - - - - - - - \ No newline at end of file +Animal.prototypeObject.prototypeRabbit.prototype[[Prototype]]rabbit[[Prototype]][[Prototype]]null[[Prototype]]= Animal.prototype? \ No newline at end of file From 7af3cf5c24e0fc825d2b4cc2d22a23318e9e3897 Mon Sep 17 00:00:00 2001 From: Carlos Ortiz Gutierrez Date: Sat, 9 May 2020 19:48:25 -0600 Subject: [PATCH 2/6] 1-09-06 Corregido 1 --- 1-js/09-classes/06-instanceof/article.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/1-js/09-classes/06-instanceof/article.md b/1-js/09-classes/06-instanceof/article.md index 4bc9f8767..849f016bd 100644 --- a/1-js/09-classes/06-instanceof/article.md +++ b/1-js/09-classes/06-instanceof/article.md @@ -65,7 +65,7 @@ El algoritmo de `obj instanceof Class` funciona más o menos de la siguiente man let obj = { canEat: true }; - alert(obj instanceof Animal); // verdadero: Animal[Symbol.hasInstance](obj) es llamadoda + alert(obj instanceof Animal); // verdadero: Animal[Symbol.hasInstance](obj) es llamada ``` 2. La mayoría de las clases no tienen `Symbol.hasInstance`. En ese caso, se utiliza la lógica estándar: `obj instanceOf Class` comprueba si `Class.prototype` es igual a uno de los prototipos en la cadena de prototipos `obj`. @@ -139,7 +139,7 @@ Esa es su implementación de `toString`. Pero hay una característica oculta que ¿Suena extraño? En efecto. Vamos a desmitificar. -Mediante [especificación](https://tc39.github.io/ecma262/#sec-object.prototype.tostring), el `toString` incorporado puede extraerse del objeto y ejecutarse en el contexto de cualquier otro valor. Y su resultado depende de ese valor. +Por esta [especificación](https://tc39.github.io/ecma262/#sec-object.prototype.tostring), el `toString` incorporado puede extraerse del objeto y ejecutarse en el contexto de cualquier otro valor. Y su resultado depende de ese valor. - Para un número, será `[object Number]` - Para un booleano, será `[objetc Boolean]` @@ -189,7 +189,7 @@ alert( {}.toString.call(user) ); // [object User] Para la mayoría de los objetos específicos del entorno, existe dicha propiedad. Aquí hay algunos ejemplos específicos del navegador: ```js run -// ttoStringTag para el objeto y clase específicos del entorno: +// toStringTag para el objeto y clase específicos del entorno: alert( window[Symbol.toStringTag]); // ventana alert( XMLHttpRequest.prototype[Symbol.toStringTag] ); // XMLHttpRequest From f95e42bb88177a9c4e0880d608271c234151c95a Mon Sep 17 00:00:00 2001 From: Carlos Ortiz Gutierrez Date: Sat, 9 May 2020 19:52:22 -0600 Subject: [PATCH 3/6] 1-09-06 Corregido 2 --- 1-js/09-classes/06-instanceof/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/09-classes/06-instanceof/article.md b/1-js/09-classes/06-instanceof/article.md index 849f016bd..8d7fa21c3 100644 --- a/1-js/09-classes/06-instanceof/article.md +++ b/1-js/09-classes/06-instanceof/article.md @@ -197,7 +197,7 @@ alert( {}.toString.call(window) ); // [object Window] alert( {}.toString.call(new XMLHttpRequest()) ); // [object XMLHttpRequest] ``` -Como puedes ver, el resultado es exactamente `Symbol.toStringTag` (si existe), envuelto en `[objetc ...]`. +Como puedes ver, el resultado es exactamente `Symbol.toStringTag` (si existe), envuelto en `[object ...]`. Al final tenemos "typeof con esteroides" que no solo funciona para tipos de datos primitivos, sino también para objetos incorporados e incluso puede personalizarse. From 254540dc88f04763b7d6348ed6708e5b9c492f24 Mon Sep 17 00:00:00 2001 From: Carlos Ortiz Gutierrez Date: Sat, 9 May 2020 23:03:47 -0600 Subject: [PATCH 4/6] 1-09-07 Traducido 7 --- 1-js/09-classes/07-mixins/article.md | 123 +++++++++--------- 1-js/09-classes/07-mixins/head.html | 12 +- .../07-mixins/mixin-inheritance.svg | 55 +------- 3 files changed, 70 insertions(+), 120 deletions(-) diff --git a/1-js/09-classes/07-mixins/article.md b/1-js/09-classes/07-mixins/article.md index 7b6d9ebad..7513da631 100644 --- a/1-js/09-classes/07-mixins/article.md +++ b/1-js/09-classes/07-mixins/article.md @@ -1,22 +1,22 @@ -# Mixins +# Los Mixins -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. +En JavaScript solo podemos heredar de un solo objeto. Solo puede haber un `[[Prototype]]` para un objeto. Y una clase puede extender solo otra clase. -But sometimes that feels limiting. For instance, I have a class `StreetSweeper` and a class `Bicycle`, and want to make a `StreetSweepingBicycle`. +Pero a veces eso se siente limitante. Por ejemplo, tenemos una clase `StreetSweeper` y una clase `Bicycle`, y queremos hacer su combinación: un `StreetSweepingBicycle`. -Or, talking about programming, we have a class `Renderer` that implements templating and a class `EventEmitter` that implements event handling, and want to merge these functionalities together with a class `Page`, to make a page that can use templates and emit events. +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. -There's a concept that can help here, called "mixins". +Hay un concepto que puede ayudar aquí, llamado "mixins". -As defined in Wikipedia, a [mixin](https://en.wikipedia.org/wiki/Mixin) is a class that contains methods for use by other classes without having to be the parent class of those other classes. +Como se define en Wikipedia, un [mixin]https://en.wikipedia.org/wiki/Mixin) es una clase que contiene métodos que pueden ser utilizados por otras clases sin necesidad de heredar de ella. -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. +En otras palabras, un *mixin* proporciona métodos que implementan cierto comportamiento, pero no lo usamos solo, lo usamos para agregar el comportamiento a otras clases. -## A mixin example +## Un ejemplo de mixin -The simplest way to make 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. +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. -For instance here the mixin `sayHiMixin` is used to add some "speech" for `User`: +Por ejemplo, aquí el mixin `sayHiMixin` se usa para agregar algo de "diálogo" a `User`: ```js run *!* @@ -24,15 +24,15 @@ For instance here the mixin `sayHiMixin` is used to add some "speech" for `User` */!* let sayHiMixin = { sayHi() { - alert(`Hello ${this.name}`); + alert(`Hola ${this.name}`); }, sayBye() { - alert(`Bye ${this.name}`); + alert(`Adios ${this.name}`); } }; *!* -// usage: +// uso: */!* class User { constructor(name) { @@ -40,14 +40,14 @@ class User { } } -// copy the methods +// copia los métodos Object.assign(User.prototype, sayHiMixin); -// now User can say hi -new User("Dude").sayHi(); // Hello Dude! +// Ahora el User puede decir hola +new User("tío").sayHi(); // Hola tío! ``` -There's no inheritance, but a simple method copying. So `User` may extend some other class and also include the mixin to "mix-in" the additional methods, like this: +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: ```js class User extends Person { @@ -57,9 +57,9 @@ class User extends Person { Object.assign(User.prototype, sayHiMixin); ``` -Mixins can make use of inheritance inside themselves. +Los mixins pueden hacer uso de la herencia dentro de sí mismos. -For instance, here `sayHiMixin` inherits from `sayMixin`: +Por ejemplo, aquí `sayHiMixin` hereda de `sayMixin`: ```js run let sayMixin = { @@ -69,16 +69,16 @@ let sayMixin = { }; let sayHiMixin = { - __proto__: sayMixin, // (or we could use Object.create to set the prototype here) + __proto__: sayMixin, // (o podríamos usar Object.create para configurar el prototype aquí) sayHi() { *!* - // call parent method + // llama al método padre */!* - super.say(`Hello ${this.name}`); + super.say(`Hola ${this.name}`); // (*) }, sayBye() { - super.say(`Bye ${this.name}`); + super.say(`Adios ${this.name}`); // (*) } }; @@ -88,39 +88,43 @@ class User { } } -// copy the methods +// copia los métodos Object.assign(User.prototype, sayHiMixin); -// now User can say hi -new User("Dude").sayHi(); // Hello Dude! +// ahora User puede decir hola +new User("tío").sayHi(); // Hola tío! ``` -Please note that the call to the parent method `super.say()` from `sayHiMixin` looks for the method in the prototype of that mixin, not the class. +Tenga 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 la clase. + +Aquí está el diagrama (ver la parte derecha): ![](mixin-inheritance.svg) -That's because methods from `sayHiMixin` have `[[HomeObject]]` set to it. So `super` actually means `sayHiMixin.__proto__`, not `User.__proto__`. +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. -## EventMixin +Como `super` busca métodos primarios en `[[HomeObject]].[[Prototype]]`, significa que busca `sayHiMixin.[[Prototype]]`, no `User.[[Prototype]]`. -Now let's make a mixin for real life. +## EventMixin -The important feature of many objects is working with events. +Ahora hagamos un mixin para la vida real. -That is: an object should have a method to "generate an event" when something important happens to it, and other objects should be able to "listen" to such events. +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. -An event must have a name and, optionally, bundle some additional data. +- 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. +- También el método `.on(name, handler)` que agrega la función `handler` como oyente 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`. +- ...Y el método `.off (name, handler)` que elimina el oyente `handler`. -For instance, an object `user` can generate an event `"login"` when the visitor logs in. And another object `calendar` may want to receive such events to load the calendar for the logged-in person. +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. -Or, a `menu` can generate the event `"select"` when a menu item is selected, and other objects may want to get that information and react on that event. +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í. -Events is a way to "share information" with anyone who wants it. They can be useful in any class, so let's make a mixin for them: +Aquí está el código: ```js run let eventMixin = { /** - * Subscribe to event, usage: + * Suscríbete al evento, uso: * menu.on('select', function(item) { ... } */ on(eventName, handler) { @@ -132,11 +136,11 @@ let eventMixin = { }, /** - * Cancel the subscription, usage: + * Cancelar la suscripción, uso: * menu.off('select', handler) */ off(eventName, handler) { - let handlers = this._eventHandlers && this._eventHandlers[eventName]; + let handlers = this._eventHandlers?.[eventName]; if (!handlers) return; for (let i = 0; i < handlers.length; i++) { if (handlers[i] === handler) { @@ -146,12 +150,12 @@ let eventMixin = { }, /** - * Generate the event and attach the data to it + * Generar un evento con el nombre y los datos * this.trigger('select', data1, data2); */ trigger(eventName, ...args) { if (!this._eventHandlers || !this._eventHandlers[eventName]) { - return; // no handlers for that event name + return; // no hay controladores para ese nombre de evento } // call the handlers @@ -160,46 +164,45 @@ let eventMixin = { }; ``` -There are 3 methods here: - -1. `.on(eventName, handler)` -- assigns function `handler` to run when the event with that name happens. The handlers are stored in the `_eventHandlers` property. -2. `.off(eventName, handler)` -- removes the function from the handlers list. -3. `.trigger(eventName, ...args)` -- generates the event: all assigned handlers are called and `args` are passed as arguments to them. +- `.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. +- `.off(eventName, handler)` - elimina la función de la lista de controladores. +- `.trigger(eventName, ... args)` - genera el evento: se llama a todos los controladores de `_eventHandlers [eventName]`, con una lista de argumentos `... args`. -Usage: +Uso: ```js run -// Make a class +// Hacer una clase class Menu { choose(value) { this.trigger("select", value); } } -// Add the mixin +// Agregue el mixin con métodos relacionados con eventos Object.assign(Menu.prototype, eventMixin); let menu = new Menu(); -// call the handler on selection: +// agregue un controlador, que se llamará en la selección: *!* -menu.on("select", value => alert(`Value selected: ${value}`)); +menu.on("select", value => alert(`Valor seleccionado: ${value}`)); */!* -// triggers the event => shows Value selected: 123 -menu.choose("123"); // value selected +// desencadena el evento => el controlador anterior se ejecuta y muestra: +// Valor seleccionado: 123 +menu.choose("123"); ``` -Now if we have the code interested to react on user selection, we can bind it with `menu.on(...)`. +Ahora, si queremos que algún código reaccione a una selección de menú, podemos escucharlo con `menu.on (...)`. -And the `eventMixin` can add such behavior to as many classes as we'd like, without interfering with the inheritance chain. +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. -## Summary +## Resumen -*Mixin* -- is a generic object-oriented programming term: a class that contains methods for other classes. +*Mixin* -- es un término genérico de programación orientado a objetos: una clase que contiene métodos para otras clases. -Some other languages like e.g. python allow to create mixins using multiple inheritance. JavaScript does not support multiple inheritance, but mixins can be implemented by copying them into the prototype. +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. -We can use mixins as a way to augment a class by multiple behaviors, like event-handling as we have seen above. +Podemos usar mixins como una forma de aumentar una clase agregando múltiples comportamientos, como el manejo de eventos que hemos visto anteriormente. -Mixins may become a point of conflict if they occasionally overwrite native class methods. So generally one should think well about the naming for a mixin, to minimize such possibility. +Los mixins pueden convertirse en un punto de conflicto si sobrescriben accidentalmente los métodos de clase existentes. Por lo tanto, generalmente uno debe pensar bien sobre la definición de métodos de un mixin, para minimizar la probabilidad de que eso suceda. diff --git a/1-js/09-classes/07-mixins/head.html b/1-js/09-classes/07-mixins/head.html index 77ea38b20..5d13ba451 100644 --- a/1-js/09-classes/07-mixins/head.html +++ b/1-js/09-classes/07-mixins/head.html @@ -2,7 +2,7 @@ let eventMixin = { /** - * Subscribe to event, usage: + * Suscríbete al evento, uso: * menu.on('select', function(item) { ... } */ on(eventName, handler) { @@ -14,11 +14,11 @@ }, /** - * Cancel the subscription, usage: + * Cancelar la suscripción, uso: * menu.off('select', handler) */ off(eventName, handler) { - let handlers = this._eventHandlers && this._eventHandlers[eventName]; + let handlers = this._eventHandlers?.[eventName]; if (!handlers) return; for(let i = 0; i < handlers.length; i++) { if (handlers[i] == handler) { @@ -28,15 +28,15 @@ }, /** - * Generate the event and attach the data to it + * Genere el evento y adjúntele los datos. * this.trigger('select', data1, data2); */ trigger(eventName, ...args) { if (!this._eventHandlers || !this._eventHandlers[eventName]) { - return; // no handlers for that event name + return; // no hay controladores para ese nombre de evento } - // call the handlers + // llama a los manejadores this._eventHandlers[eventName].forEach(handler => handler.apply(this, args)); } }; diff --git a/1-js/09-classes/07-mixins/mixin-inheritance.svg b/1-js/09-classes/07-mixins/mixin-inheritance.svg index c1ce62f91..aaa8cb7d0 100644 --- a/1-js/09-classes/07-mixins/mixin-inheritance.svg +++ b/1-js/09-classes/07-mixins/mixin-inheritance.svg @@ -1,54 +1 @@ - - - - mixin-inheritance.svg - Created with sketchtool. - - - - - sayHi: function - sayBye: function - - - sayHiMixin - - - - say: function - - - sayMixin - - - - [[Prototype]] - - - - constructor: User - sayHi: function - sayBye: function - - - User.prototype - - - - - - [[Prototype]] - - - - name: ... - - - user - - - [[HomeObject] - - - - \ No newline at end of file +sayHi: function sayBye: functionsayHiMixinsay: functionsayMixin[[Prototype]]constructor: User sayHi: function sayBye: functionUser.prototype[[Prototype]]name: ...user[[HomeObject] \ No newline at end of file From 79b2c9fbab2be93d48249b9b8b1d0fa0eadc9dd2 Mon Sep 17 00:00:00 2001 From: Carlos Ortiz Gutierrez Date: Sat, 9 May 2020 23:14:49 -0600 Subject: [PATCH 5/6] 1-09-07 Corregido 3 --- 1-js/09-classes/07-mixins/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/09-classes/07-mixins/article.md b/1-js/09-classes/07-mixins/article.md index 7513da631..43c2fdc97 100644 --- a/1-js/09-classes/07-mixins/article.md +++ b/1-js/09-classes/07-mixins/article.md @@ -113,7 +113,7 @@ Una característica importante de muchos objetos del navegador (por ejemplo) es - 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. - También el método `.on(name, handler)` que agrega la función `handler` como oyente 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`. -- ...Y el método `.off (name, handler)` que elimina el oyente `handler`. +- ...Y el método `.off(name, handler)` que elimina el oyente `handler`. 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. From 4c0250a129e62960b7e0b366f05c3b5bef4ae9f7 Mon Sep 17 00:00:00 2001 From: Carlos Ortiz Gutierrez Date: Sat, 9 May 2020 23:16:57 -0600 Subject: [PATCH 6/6] 1-09-07 Corregido 4 --- 1-js/09-classes/07-mixins/article.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-js/09-classes/07-mixins/article.md b/1-js/09-classes/07-mixins/article.md index 43c2fdc97..437a0084e 100644 --- a/1-js/09-classes/07-mixins/article.md +++ b/1-js/09-classes/07-mixins/article.md @@ -193,7 +193,7 @@ menu.on("select", value => alert(`Valor seleccionado: ${value}`)); menu.choose("123"); ``` -Ahora, si queremos que algún código reaccione a una selección de menú, podemos escucharlo con `menu.on (...)`. +Ahora, si queremos que algún código reaccione a una selección de menú, podemos escucharlo con `menu.on(...)`. 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. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy