2011-12-20 8 views
15

¿Podría alguien explicar lo siguiente?Instancia de inconsistencia

[] instanceof Array; // true 
'' instanceof String; // false 
+1

También 'typeof" "' es '" cadena "' y 'typeof []' es '" objeto "' (usted esperaría '" array "' pero bien, puedo vivir con eso) – Halcyon

+0

Adivinando, podría '' ser un primitivo, pero [] un objeto? –

+2

+1 Interesante, porque '" ".constructor === String'. – pimvdb

Respuesta

14

en cuenta lo siguiente:

"" instanceof String;    // => false 
new String("") instanceof String; // => true 

instanceof requiere un objeto, pero "" es una cadena literal, y no un objeto String. Tenga en cuenta los siguientes tipos mediante la función typeof:

typeof ""    // => "string" 
typeof new String("") // => "object" 
typeof []    // => "object" 
typeof new Array() // => "object" 
+0

¿Cuál es la diferencia entre un objeto 'literal string' y' String' y por qué es (aparentemente) importante? Por lo que sé, se pueden usar indistintamente, pero el resultado es que no se puede usar 'instanceof' para verificar si algo es una 'cadena' – Halcyon

+1

, pero no es' [] 'una matriz literal de la misma manera que' '' '¿es una cadena literal? – FishBasketGordo

+0

@FishBasketGordo array puede contener todo tipo de primitivas y objetos. –

11

Es porque '' es primitivo, no un objeto.

Algunas primitivas en JavaScript pueden tener un contenedor de objetos. Se crean cuando crea una instancia del contenedor utilizando el constructor incorporado con new.

El new suele ser necesario porque muchas veces la función forzará a una primitiva si excluye new.

typeof new String(''); // "object" 
typeof String('');  // "string" 
typeof '';    // "string" 

Las primitivas que tienen envolturas de objetos son string, number y boolean.

Las primitivas que no son null y undefined.

+0

Entonces, ¿cuál es la primitiva (es decir, el objeto no envoltorio) de '[]'? – Randomblue

+2

Randomblue: No hay uno. Una matriz es siempre un objeto. –

+0

@Randomblue no existe. ¿Por qué habría un primitivo? – Raynos

3

'' no es una instancia de nada; es un tipo primitivo, y funciona de manera muy similar a 5.5 o true. Hay una diferencia entre una primitiva de cadena y un objeto de cadena. Ver:

new String('') instanceof String; // true 

Cualquier cosa creada con new String(), new Number() o new Boolean() es una envoltura alrededor del objeto tipo primitivo, y no son lo mismo.

para comprobar si hay cuerdas, etc., utilice typeof lugar:

typeof '' === 'string'; // true 

para comprobar si hay tanto, utilice esto:

Object.prototype.toString.call('') === '[object String]'; // true 
Object.prototype.toString.call(new String('')) === '[object String]'; // true 

Hay un par de razones para usar para Object.prototype.toString.call código de uso general, para matrices, cadenas, números y booleanos. Ellos son:

  1. Para cadenas, números y booleanos, las personas pueden pasar instancias de los objetos de envoltura en lugar de los tipos primitivos. Por lo general, funcionan de la misma manera (con un implícito valueOf()) por lo que debe aceptarlos si escribe el código de la biblioteca.
  2. Para matrices, si recibe una serie desde otra ventana (digamos de un) a continuación, utilizando instanceof Array regresará false. El método Object.prototype.toString.call funciona para todos los propósitos.

Esto es lo que hacen jQuery y otras bibliotecas grandes y populares.

1

He hecho algunas excavaciones y supongo que tiene que ver con string interning que es una optimización del compilador.

Bien, ¿listo para algunos inconvenientes? : D

"abc" == "abc"; // true 
"abc" === "abc"; // true 

supongo que esto es verdad debido a la "cadena de internar", que casualmente también tiene mucho sentido, conceptualmente (yay para conseguir 'cuerdas' a la derecha).

new String("abc") == new String("abc"); // false 
new String("abc") === new String("abc"); // false 

Esto tiene sentido si se asume un String es un objeto y un objeto sólo es igual a sí mismo y no es igual a un objeto con el estado interno similar. Al igual que en Java (o cómo solía ser de todos modos).

Y ahora viene lo bueno:

(new String("abc")).substr(0,3) === (new String("abc")).substr(0,3); // true! 

Así que al parecer el intérprete de JavaScript siempre preferirán cadena de internar sobre el uso del objeto String.

Entonces debo preguntar, ¿para qué sirve el objeto String? Aparentemente no funciona bien con sus amigos.

+0

El primero, '" abc "===" abc "', no se debe al interrogatorio de cadenas. La igualdad estricta funciona como esperarías para los tipos primitivos. '===' es solo "igual a la referencia" para los objetos. – Ryan

+0

The String 'type' solo está ahí para permitirle extender su prototipo y también para permitirle crear cadenas similares a 'Objects'. Es decir, los objetos (similares a los punteros en C) solo serán '===' si son 'el mismo puntero' – Adaptabi

Cuestiones relacionadas