type array javascript literals instanceof

javascript - array - ¿Por qué instanceof devuelve false para algunos literales?



javascript instanceof function (9)

Creo que he encontrado una solución viable:

Object.getPrototypeOf(''test'') === String.prototype //true Object.getPrototypeOf(1) === String.prototype //false

"foo" instanceof String //=> false "foo" instanceof Object //=> false true instanceof Boolean //=> false true instanceof Object //=> false false instanceof Boolean //=> false false instanceof Object //=> false // the tests against Object really don''t make sense

Literales de matrices y literales de objetos ...

[0,1] instanceof Array //=> true {0:1} instanceof Object //=> true

¿Por qué no todos ellos? O, ¿por qué no todos no ?
Y, ¿de qué son una instancia, entonces?

Es lo mismo en FF3, IE7, Opera y Chrome. Entonces, al menos es consistente.

Perdí algunos

12.21 instanceof Number //=> false /foo/ instanceof RegExp //=> true


En JavaScript, todo es un objeto (o al menos puede tratarse como un objeto), excepto los primitives (booleanos, nulos, números, cadenas y el valor undefined (y el símbolo en ES6)):

console.log(typeof true); // boolean console.log(typeof 0); // number console.log(typeof ""); // string console.log(typeof undefined); // undefined console.log(typeof null); // object console.log(typeof []); // object console.log(typeof {}); // object console.log(typeof function () {}); // function

Como puede ver los objetos, las matrices y el valor null se consideran objetos ( null es una referencia a un objeto que no existe). Las funciones se distinguen porque son un tipo especial de objetos que se pueden llamar . Sin embargo siguen siendo objetos.

Por otro lado, los literales true , 0 , "" y undefined no son objetos. Son valores primitivos en JavaScript. Sin embargo, los valores booleanos, los números y las cadenas también tienen constructores Boolean , Number y String respectivamente que envuelven sus respectivas primitivas para proporcionar funcionalidad adicional:

console.log(typeof new Boolean(true)); // object console.log(typeof new Number(0)); // object console.log(typeof new String("")); // object

Como puede ver, cuando los valores primitivos se ajustan dentro de los constructores Boolean , Number y String respectivamente, se convierten en objetos. El operador instanceof solo funciona para objetos (por lo que devuelve false para valores primitivos):

console.log(true instanceof Boolean); // false console.log(0 instanceof Number); // false console.log("" instanceof String); // false console.log(new Boolean(true) instanceof Boolean); // true console.log(new Number(0) instanceof Number); // true console.log(new String("") instanceof String); // true

Como puede ver, tanto typeof como instanceof no son suficientes para probar si un valor es un valor booleano, un número o una cadena - typeof solo funciona para valores booleanos primitivos, números y cadenas; y instanceof no funciona para booleanos primitivos, números y cadenas.

Afortunadamente hay una solución simple para este problema. La implementación predeterminada de toString (es decir, como se define de forma nativa en Object.prototype.toString ) devuelve la propiedad interna [[Class]] de los valores y objetos primitivos:

function classOf(value) { return Object.prototype.toString.call(value); } console.log(classOf(true)); // [object Boolean] console.log(classOf(0)); // [object Number] console.log(classOf("")); // [object String] console.log(classOf(new Boolean(true))); // [object Boolean] console.log(classOf(new Number(0))); // [object Number] console.log(classOf(new String(""))); // [object String]

La propiedad interna [[Class]] de un valor es mucho más útil que el tipo del valor. Podemos usar Object.prototype.toString para crear nuestra propia versión (más útil) del operador typeof siguiente manera:

function typeOf(value) { return Object.prototype.toString.call(value).slice(8, -1); } console.log(typeOf(true)); // Boolean console.log(typeOf(0)); // Number console.log(typeOf("")); // String console.log(typeOf(new Boolean(true))); // Boolean console.log(typeOf(new Number(0))); // Number console.log(typeOf(new String(""))); // String

Espero que este artículo haya ayudado. Para saber más sobre las diferencias entre los primitivos y los objetos envueltos, lea la siguiente entrada del blog: La vida secreta de los primitivos de JavaScript


Los primitivos son un tipo de tipo diferente a los objetos creados desde Javascript. De la documentación de la API de Mozilla :

var color1 = new String("green"); color1 instanceof String; // returns true var color2 = "coral"; color2 instanceof String; // returns false (color2 is not a String object)

No encuentro ninguna forma de construir tipos primitivos con código, tal vez no sea posible. Probablemente esta sea la razón por la que la gente usa typeof "foo" === "string" lugar de instanceof .

Una forma fácil de recordar cosas como esta es preguntarse: "Me pregunto qué sería lo más sensato y fácil de aprender". Cualquiera que sea la respuesta, Javascript hace lo otro.


O simplemente puedes hacer tu propia función así:

function isInstanceOf(obj, clazz){ return (obj instanceof eval("("+clazz+")")) || (typeof obj == clazz.toLowerCase()); };

uso:

isInstanceOf('''',''String''); isInstanceOf(new String(), ''String'');

Estos deben devolver ambos verdaderos.


Para mí la confusión causada por

"str".__proto__ // #1 => String

Por lo tanto, "str" istanceof String debería devolver true porque la "istanceof" funciona de la siguiente manera:

"str".__proto__ == String.prototype // #2 => true

Los resultados de la expresión # 1 y # 2 entran en conflicto entre sí, por lo que debe haber uno de ellos incorrecto.

# 1 está mal

Me doy cuenta de que la causa __proto__ no es una propiedad estándar, así que usa la estándar: Object.getPrototypeOf

Object.getPrototypeOf("str") // #3 => TypeError: Object.getPrototypeOf called on non-object

Ahora no hay confusión entre la expresión # 2 y # 3


Puedes usar la propiedad del constructor:

''foo''.constructor == String // returns true true.constructor == Boolean // returns true


Yo suelo:

function isString(s) { return typeof(s) === ''string'' || s instanceof String; }

Porque en JavaScript las cadenas pueden ser literales u objetos.


https://www.npmjs.com/package/typeof

Devuelve una representación de cadena de instanceof (el nombre de los constructores)

function instanceOf(object) { var type = typeof object if (type === ''undefined'') { return ''undefined'' } if (object) { type = object.constructor.name } else if (type === ''object'') { type = Object.prototype.toString.call(object).slice(8, -1) } return type.toLowerCase() } instanceOf(false) // "boolean" instanceOf(new Promise(() => {})) // "promise" instanceOf(null) // "null" instanceOf(undefined) // "undefined" instanceOf(1) // "number" instanceOf(() => {}) // "function" instanceOf([]) // "array"


typeof(text) === ''string'' || text instanceof String;

Puedes usar esto, funcionará tanto para el caso como para

  1. var text="foo"; // typeof funcionará

  2. String text= new String("foo"); // instanceof funcionará