Pergunta

"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

literais de matriz e literais objeto Match ...

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

Por que nem todos eles? Ou, por que nem todos eles não ?
E, o que eles são uma instância de, então?

É o mesmo no FF3, IE7, Opera e Chrome. Assim, pelo menos é consistente.


perdeu alguns.

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

Solução

Primitives são um tipo diferente de tipo de objetos criados a partir de dentro Javascript. Do 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)

Não consigo encontrar alguma maneira de construir tipos primitivos com código, talvez não seja possível. Este é provavelmente porque as pessoas usam typeof "foo" === "string" vez de instanceof.

Uma maneira fácil de lembrar coisas como esta está se perguntando "Eu me pergunto o que seria sensato e fácil de aprender"? Seja qual for a resposta é, Javascript faz a outra coisa.

Outras dicas

Eu uso:

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

Porque em JavaScript cordas podem ser literais ou objetos.

Em JavaScript tudo é um objecto (ou pode pelo menos ser tratada como um objecto), excepto primitivas (booleans, null, números, strings e o undefined valor (e símbolo no 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 você pode ver objetos, matrizes e o valor null são todos os objetos considerados (null é uma referência a um objeto que não existe). Funções são distinguidos porque eles são um tipo especial de exigível objetos. No entanto, eles ainda são objetos.

Por outro lado, os literais true, 0, "" e undefined não são objetos. Eles são valores primitivos em JavaScript. No entanto booleans, números e strings também têm construtores Boolean, Number e String respectivamente, que envolva seus respectivos primitivos para fornecer funcionalidades adicionais:

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

Como você pode ver quando os valores primitivos são enrolados dentro dos construtores Boolean, Number e String respectivamente tornam-se objetos. O operador instanceof só funciona para objetos (que é por isso que ele retorna 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 você pode ver tanto typeof e instanceof são insuficientes para testar se um valor é um boolean, um número ou uma string - typeof só funciona para booleanos primitivos, números e strings; e instanceof não funciona para booleanos primitivos, números e strings.

Felizmente há uma solução simples para esse problema. A implementação padrão de toString (ou seja, como é nativamente definido em Object.prototype.toString) retorna a propriedade [[Class]] interna de ambos os valores e 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]

A propriedade [[Class]] interna de um valor é muito mais útil do que o typeof o valor. Podemos usar Object.prototype.toString para criar nossa própria versão (mais útil) do operador typeof da seguinte forma:

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 artigo ajudou. Para saber mais sobre as diferenças entre primitivos e objetos embrulhados ler o seguinte post: A vida secreta das JavaScript Primitives

Você pode usar a propriedade construtor:

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

Você pode usar isso, ele vai trabalhar para ambos os casos como

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

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

Acredito que tenho chegar a uma solução viável:

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

Esta é definido no ECMAScript especificação Seção 7.3.19 Passo 3 : If Type(O) is not Object, return false.

Em outras palavras, se o Obj em Obj instanceof Callable não é um objeto, o instanceof irá curto-circuito para false diretamente.

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

Retorna uma string-representação das instanceof (o nome construtores)

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 mim, a confusão causada por

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

Assim "str" istanceof String deve retornar true porque como istanceof funciona como abaixo:

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

Os resultados de expressão # 1 e # 2 conflito entre si, por isso não deve ser um deles errado.

# 1 está errado

Eu descobrir o que causou pelo __proto__ é propriedade não padrão, então use o padrão: Object.getPrototypeOf

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

Agora, não há confusão entre a expressão # 2 e # 3

Ou você pode simplesmente fazer a sua própria função assim:

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

uso:

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

Estes devem tanto return true.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top