Skip to content

Commit aec3d5c

Browse files
authored
Merge pull request #175 from cortizg/es.javascript.info.1-09-06
Class checking: "instanceof"
2 parents 404071b + ad9cd05 commit aec3d5c

File tree

3 files changed

+81
-81
lines changed

3 files changed

+81
-81
lines changed
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
Yeah, looks strange indeed.
1+
Sí, se ve extraño de hecho.
22

3-
But `instanceof` does not care about the function, but rather about its `prototype`, that it matches against the prototype chain.
3+
Pero a `instanceof` no le importa la función, sino más bien su `prototype`, que coincide con la cadena del prototipo.
44

5-
And here `a.__proto__ == B.prototype`, so `instanceof` returns `true`.
5+
Y aquí `a.__ proto__ == B.prototype`, entonces `instanceof` devuelve `true`.
66

7-
So, by the logic of `instanceof`, the `prototype` actually defines the type, not the constructor function.
7+
Entonces, según la lógica de `instanceof`, el `prototype` en realidad define el tipo, no la función constructora.

1-js/09-classes/06-instanceof/1-strange-instanceof/task.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ importance: 5
22

33
---
44

5-
# Strange instanceof
5+
# Extraño instanceof
66

7-
In the code below, why does `instanceof` return `true`? We can easily see that `a` is not created by `B()`.
7+
En el siguiente código, ¿por qué `instanceof` devuelve `true`? Podemos ver fácilmente que `a` no es creado por `B()`.
88

99
```js run
1010
function A() {}
@@ -15,6 +15,6 @@ A.prototype = B.prototype = {};
1515
let a = new A();
1616

1717
*!*
18-
alert( a instanceof B ); // true
18+
alert( a instanceof B ); // verdadero
1919
*/!*
2020
```
Lines changed: 74 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,62 @@
1-
# Class checking: "instanceof"
1+
# Comprobación de clase: "instanceof"
22

3-
The `instanceof` operator allows to check whether an object belongs to a certain class. It also takes inheritance into account.
3+
El operador `instanceof` permite verificar si un objeto pertenece a una clase determinada. También tiene en cuenta la herencia.
44

5-
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.
5+
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.
66

7-
## The instanceof operator [#ref-instanceof]
7+
## El operador instanceof [#ref-instanceof]
88

9-
The syntax is:
9+
La sintaxis es:
1010
```js
1111
obj instanceof Class
1212
```
13+
Devuelve `true` si `obj` pertenece a la `Class` o una clase que hereda de ella.
1314

14-
It returns `true` if `obj` belongs to the `Class` or a class inheriting from it.
15-
16-
For instance:
15+
Por ejemplo:
1716

1817
```js run
1918
class Rabbit {}
2019
let rabbit = new Rabbit();
2120

22-
// is it an object of Rabbit class?
21+
// ¿Es un objeto de la clase Rabbit?
2322
*!*
24-
alert( rabbit instanceof Rabbit ); // true
23+
alert( rabbit instanceof Rabbit ); // verdadero
2524
*/!*
2625
```
2726

28-
It also works with constructor functions:
27+
También funciona con funciones de constructor:
2928

3029
```js run
3130
*!*
32-
// instead of class
31+
// en lugar de clase
3332
function Rabbit() {}
3433
*/!*
3534

36-
alert( new Rabbit() instanceof Rabbit ); // true
35+
alert( new Rabbit() instanceof Rabbit ); // verdadero
3736
```
3837

39-
...And with built-in classes like `Array`:
38+
...Y con clases integradas como `Array`:
4039

4140
```js run
4241
let arr = [1, 2, 3];
43-
alert( arr instanceof Array ); // true
44-
alert( arr instanceof Object ); // true
42+
alert( arr instanceof Array ); // verdadero
43+
alert( arr instanceof Object ); // verdadero
4544
```
4645

47-
Please note that `arr` also belongs to the `Object` class. That's because `Array` prototypically inherits from `Object`.
46+
Tenga en cuenta que `arr` también pertenece a la clase `Object`. Esto se debe a que `Array` hereda prototípicamente de `Object`.
4847

49-
Normally, `instanceof` examines the prototype chain for the check. We can also set a custom logic in the static method `Symbol.hasInstance`.
48+
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`.
5049

51-
The algorithm of `obj instanceof Class` works roughly as follows:
50+
El algoritmo de `obj instanceof Class` funciona más o menos de la siguiente manera:
5251

53-
1. If there's a static method `Symbol.hasInstance`, then just call it: `Class[Symbol.hasInstance](obj)`. It should return either `true` or `false`, and we're done. That's how we can customize the behavior of `instanceof`.
52+
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`.
5453

55-
For example:
54+
Por ejemplo:
5655

5756
```js run
58-
// setup instanceOf check that assumes that
59-
// anything with canEat property is an animal
57+
// Instalar instancia de verificación que asume que
58+
// cualquier cosa con propiedad canEat es un animal
59+
6060
class Animal {
6161
static [Symbol.hasInstance](obj) {
6262
if (obj.canEat) return true;
@@ -65,104 +65,105 @@ The algorithm of `obj instanceof Class` works roughly as follows:
6565

6666
let obj = { canEat: true };
6767

68-
alert(obj instanceof Animal); // true: Animal[Symbol.hasInstance](obj) is called
68+
alert(obj instanceof Animal); // verdadero: Animal[Symbol.hasInstance](obj) es llamada
6969
```
7070

71-
2. Most classes do not have `Symbol.hasInstance`. In that case, the standard logic is used: `obj instanceOf Class` checks whether `Class.prototype` is equal to one of the prototypes in the `obj` prototype chain.
71+
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`.
72+
73+
En otras palabras, compara uno tras otro:
7274

73-
In other words, compare one after another:
7475
```js
7576
obj.__proto__ === Class.prototype?
7677
obj.__proto__.__proto__ === Class.prototype?
7778
obj.__proto__.__proto__.__proto__ === Class.prototype?
7879
...
79-
// if any answer is true, return true
80-
// otherwise, if we reached the end of the chain, return false
80+
// si alguna respuesta es verdadera, devuelve true
81+
// de lo contrario, si llegamos al final de la cadena, devuelve false
8182
```
8283

83-
In the example above `rabbit.__proto__ === Rabbit.prototype`, so that gives the answer immediately.
84+
En el ejemplo anterior `rabbit.__ proto__ === Rabbit.prototype`, por lo que da la respuesta de inmediato.
8485

85-
In the case of an inheritance, the match will be at the second step:
86+
En el caso de una herencia, la coincidencia será en el segundo paso:
8687

8788
```js run
8889
class Animal {}
8990
class Rabbit extends Animal {}
9091
9192
let rabbit = new Rabbit();
9293
*!*
93-
alert(rabbit instanceof Animal); // true
94+
alert(rabbit instanceof Animal); // verdadero
9495
*/!*
9596
9697
// rabbit.__proto__ === Rabbit.prototype
9798
*!*
98-
// rabbit.__proto__.__proto__ === Animal.prototype (match!)
99+
// rabbit.__proto__.__proto__ === Animal.prototype (iguala!)
99100
*/!*
100101
```
101102

102-
Here's the illustration of what `rabbit instanceof Animal` compares with `Animal.prototype`:
103+
Aquí está la ilustración de lo que `rabbit instanceof Animal` compara con `Animal.prototype`:
103104

104105
![](instanceof.svg)
105106

106-
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)`.
107+
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)`.
107108

108-
It's funny, but the `Class` constructor itself does not participate in the check! Only the chain of prototypes and `Class.prototype` matters.
109+
Es divertido, ¡pero el constructor `Class` en sí mismo no participa en el chequeo! Solo importa la cadena de prototipos y `Class.prototype`.
109110

110-
That can lead to interesting consequences when a `prototype` property is changed after the object is created.
111+
Eso puede llevar a consecuencias interesantes cuando se cambia una propiedad `prototype` después de crear el objeto.
111112

112-
Like here:
113+
Como aquí:
113114

114115
```js run
115116
function Rabbit() {}
116117
let rabbit = new Rabbit();
117118

118-
// changed the prototype
119+
// cambió el prototipo
119120
Rabbit.prototype = {};
120121

121-
// ...not a rabbit any more!
122+
// ...ya no es un conejo!
122123
*!*
123-
alert( rabbit instanceof Rabbit ); // false
124+
alert( rabbit instanceof Rabbit ); // falso
124125
*/!*
125126
```
126127

127-
## Bonus: Object.prototype.toString for the type
128+
## Bonificación: Object.prototype.toString para el tipo
128129

129-
We already know that plain objects are converted to string as `[object Object]`:
130+
Ya sabemos que los objetos simples se convierten en cadenas como `[objetc Objetc]`:
130131

131132
```js run
132133
let obj = {};
133134

134135
alert(obj); // [object Object]
135-
alert(obj.toString()); // the same
136+
alert(obj.toString()); // lo mismo
136137
```
137138

138-
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`.
139+
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`.
139140

140-
Sounds strange? Indeed. Let's demystify.
141+
¿Suena extraño? En efecto. Vamos a desmitificar.
141142

142-
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.
143+
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.
143144

144-
- For a number, it will be `[object Number]`
145-
- For a boolean, it will be `[object Boolean]`
146-
- For `null`: `[object Null]`
147-
- For `undefined`: `[object Undefined]`
148-
- For arrays: `[object Array]`
149-
- ...etc (customizable).
145+
- Para un número, será `[object Number]`
146+
- Para un booleano, será `[objetc Boolean]`
147+
- Para `null`: `[objetc Null]`
148+
- Para `undefined`: `[objetc Undefined]`
149+
- Para matrices: `[Object Array]`
150+
- ... etc (personalizable).
150151

151-
Let's demonstrate:
152+
Demostremos:
152153

153154
```js run
154-
// copy toString method into a variable for convenience
155+
// copie el método toString en una variable a conveniencia
155156
let objectToString = Object.prototype.toString;
156157

157-
// what type is this?
158+
// ¿que tipo es este?
158159
let arr = [];
159160

160161
alert( objectToString.call(arr) ); // [object *!*Array*/!*]
161162
```
162163

163-
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`.
164+
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`.
164165

165-
Internally, the `toString` algorithm examines `this` and returns the corresponding result. More examples:
166+
Internamente, el algoritmo `toString` examina `this` y devuelve el resultado correspondiente. Más ejemplos:
166167

167168
```js run
168169
let s = Object.prototype.toString;
@@ -174,9 +175,9 @@ alert( s.call(alert) ); // [object Function]
174175

175176
### Symbol.toStringTag
176177

177-
The behavior of Object `toString` can be customized using a special object property `Symbol.toStringTag`.
178+
El comportamiento del objeto `toString` se puede personalizar utilizando una propiedad de objeto especial `Symbol.toStringTag`.
178179

179-
For instance:
180+
Por ejemplo:
180181

181182
```js run
182183
let user = {
@@ -185,34 +186,33 @@ let user = {
185186

186187
alert( {}.toString.call(user) ); // [object User]
187188
```
188-
189-
For most environment-specific objects, there is such a property. Here are some browser specific examples:
189+
Para la mayoría de los objetos específicos del entorno, existe dicha propiedad. Aquí hay algunos ejemplos específicos del navegador:
190190

191191
```js run
192-
// toStringTag for the environment-specific object and class:
193-
alert( window[Symbol.toStringTag]); // window
192+
// toStringTag para el objeto y clase específicos del entorno:
193+
alert( window[Symbol.toStringTag]); // ventana
194194
alert( XMLHttpRequest.prototype[Symbol.toStringTag] ); // XMLHttpRequest
195195

196196
alert( {}.toString.call(window) ); // [object Window]
197197
alert( {}.toString.call(new XMLHttpRequest()) ); // [object XMLHttpRequest]
198198
```
199199

200-
As you can see, the result is exactly `Symbol.toStringTag` (if exists), wrapped into `[object ...]`.
200+
Como puedes ver, el resultado es exactamente `Symbol.toStringTag` (si existe), envuelto en `[object ...]`.
201201

202-
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.
202+
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.
203203

204-
We can use `{}.toString.call` instead of `instanceof` for built-in objects when we want to get the type as a string rather than just to check.
204+
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.
205205

206-
## Summary
206+
## Resumen
207207

208-
Let's summarize the type-checking methods that we know:
208+
Resumamos los métodos de verificación de tipos que conocemos:
209209

210-
| | works for | returns |
210+
| | trabaja para | retorna |
211211
|---------------|-------------|---------------|
212-
| `typeof` | primitives | string |
213-
| `{}.toString` | primitives, built-in objects, objects with `Symbol.toStringTag` | string |
214-
| `instanceof` | objects | true/false |
212+
| `typeof` | primitivos | cadena |
213+
| `{}.toString` | primitivos, objetos incorporados, objetos con `Symbol.toStringTag` | cadena |
214+
| `instanceof` | objetos | true/false |
215215

216-
As we can see, `{}.toString` is technically a "more advanced" `typeof`.
216+
Como podemos ver, `{}.toString` es técnicamente un `typeof` "más avanzado".
217217

218-
And `instanceof` operator really shines when we are working with a class hierarchy and want to check for the class taking into account inheritance.
218+
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.

0 commit comments

Comments
 (0)