Pregunta

"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

Los literales de matriz y los literales de objeto coinciden ...

[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.


Faltan algunos.

12.21 instanceof Number //=> false
/foo/ instanceof RegExp //=> true
¿Fue útil?

Solución

Las primitivas son un tipo diferente de tipo que los objetos creados desde Javascript. Del Mozilla API docs :

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 puedo encontrar ninguna manera de construir tipos primitivos con código, quizás no sea posible. Esta es probablemente la razón por la cual las personas usan typeof " foo " === " string " en lugar de instanceof .

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

Otros consejos

Yo uso:

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

Porque en JavaScript las cadenas pueden ser literales u objetos.

En JavaScript todo es un objeto (o al menos puede ser tratado como un objeto), excepto primitivas (booleanos, nulos, números, cadenas y el valor undefined (y 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 invocables . 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 booleanos, los números y las cadenas también tienen constructores Boolean , Number y String respectivamente, que envuelven sus primitivas respectivas 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 envuelven 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 son insuficientes para probar si un valor es un valor booleano, un número o una cadena - typeof solo funciona para booleanos primitivos, números y cadenas; y instanceof no funciona para booleanos, números y cadenas primitivos.

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 ambos 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 typeof del valor. Podemos usar Object.prototype.toString para crear nuestra propia versión (más útil) del operador typeof de la 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 acerca de las diferencias entre primitivas y objetos envueltos, lea la siguiente publicación de blog: La vida secreta de JavaScript & nbsp; Primitivas

Puede usar la propiedad del constructor:

'foo'.constructor == String // returns true
true.constructor == Boolean // returns true
 typeof(text) === 'string' || text instanceof String; 

puede usar esto, funcionará para ambos casos como

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

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

Creo que se me ocurrió una solución viable:

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

Esto se define en la especificación ECMAScript Sección 7.3.19 Paso 3 : Si el Tipo (O) no es Object, devuelve false.

En otras palabras, si el Obj en Obj instanceof Callable no es un objeto, el instanceof se cortocircuitará a falso directamente.

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

Devuelve una representación de cadena de instanceof (el nombre del constructor)

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"

Para mí, la confusión causada por

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

Entonces " str " istanceof String debería devolver true porque cómo istanceof funciona de la siguiente manera:

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

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

# 1 está mal

Supongo que el __proto__ es una propiedad no estándar, así que use 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

O simplemente puede hacer su propia función así:

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

uso:

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

Ambos deberían devolver verdadero.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top