Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Mixins#177

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
cortizg wants to merge7 commits intojavascript-tutorial:masterfromcortizg:es.javascript.info.1-09-07
Closed
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -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.
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,9 +2,9 @@ importance: 5

---

#Strange instanceof
#Extraño instanceof

In the code below, why does `instanceof`return `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() {}
Expand All@@ -15,6 +15,6 @@ A.prototype = B.prototype = {};
let a = new A();

*!*
alert( a instanceof B ); //true
alert( a instanceof B ); //verdadero
*/!*
```
147 changes: 74 additions & 73 deletions1-js/09-classes/06-instanceof/article.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,168 +1,169 @@
#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`prototypically 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`.

Normally, `instanceof`examines the prototype chain for the check. We can also set a custom logic in 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 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`.
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`.

For example:
Por ejemplo:

```js run
// setup instanceOf check that assumes that
// anything with canEat property 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;
}
}

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 llamada
```

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.
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 one after another:
En otras palabras, compara uno tras otro:

```js
obj.__proto__ === Class.prototype?
obj.__proto__.__proto__ === Class.prototype?
obj.__proto__.__proto__.__proto__ === Class.prototype?
...
//if any answer is true, return true
//otherwise, if we reached the end of the chain, return false
//si alguna respuesta es verdadera, devuelve true
//de lo contrario, si llegamos al final de la cadena, devuelve false
```

In the example above `rabbit.__proto__=== Rabbit.prototype`,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, the match will be at the second step:
En el caso de una herencia, la coincidencia será en el segundo paso:

```js run
class Animal {}
class Rabbit extends Animal {}

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

It'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 a`prototype`property is changed after the object is created.
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
*/!*
```

##Bonus: Object.prototype.toStringfor the type
##Bonificación: Object.prototype.toStringpara 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.
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.

-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 avariablefor convenience
//copie el método toString en unavariablea conveniencia
let objectToString = Object.prototype.toString;

//what type is this?
//¿que tipo es este?
let arr = [];

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;
Expand All@@ -174,9 +175,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 = {
Expand All@@ -186,33 +187,33 @@ let user = {
alert( {}.toString.call(user) ); // [object User]
```

For most environment-specific objects, there is such a property. Here are some 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
// toStringTagfor the environment-specific object and class:
alert( window[Symbol.toStringTag]); //window
// toStringTagpara 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 `[object ...]`.

At the end we have"typeofon steroids" that not only works for primitive data types, but also for built-in objects and even can be customized.
Al final tenemos"typeofcon esteroides" que no solo funciona para tipos de datos primitivos, sino también para objetos incorporados e incluso puede personalizarse.

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.
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 summarize 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.
Loading

[8]ページ先頭

©2009-2025 Movatter.jp