Question

"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

Les littéraux de tableau et les littéraux d'objet correspondent ...

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

Pourquoi ne pas tous? Ou pourquoi ne pas tous pas ?
Et de quoi sont-ils une instance, alors?

C'est la même chose dans FF3, IE7, Opera et Chrome. Donc, au moins c'est cohérent.

Vous avez manqué quelques-uns.

12.21 instanceof Number //=> false
/foo/ instanceof RegExp //=> true
Était-ce utile?

La solution

Les primitives sont d'un type différent des objets créés à partir de Javascript. Documents de l'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)

Je ne trouve aucun moyen de construire des types primitifs avec du code, ce n'est peut-être pas possible. C’est probablement pour cette raison que les gens utilisent typeof " foo " === "chaîne" au lieu de instance de .

Une façon simple de se souvenir de choses comme celle-ci est de se demander: "Je me demande ce qui serait sain et facile à apprendre". Quelle que soit la réponse, Javascript fait autre chose.

Autres conseils

j'utilise:

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

Parce qu'en JavaScript, les chaînes peuvent être des littéraux ou des objets.

En JavaScript, tout est un objet (ou peut au moins être traité comme un objet), sauf primitives (booléens, null, nombres, chaînes et la valeur undefined (et le symbole dans 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

Comme vous pouvez le voir, les tableaux et la valeur null sont tous des objets considérés ( null est une référence à un objet qui n'existe pas). Les fonctions sont distinguées car elles constituent un type spécial d’objets appelables . Cependant, ce sont toujours des objets.

D'autre part, les littéraux true , 0 , "" " et non défini ne sont pas des objets. . Ce sont des valeurs primitives en JavaScript. Toutefois, les booléens, les nombres et les chaînes ont également les constructeurs Boolean , Number et String qui enveloppent leurs primitives respectives pour fournir une fonctionnalité supplémentaire:

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

Comme vous pouvez le constater lorsque des valeurs primitives sont encapsulées dans les constructeurs Boolean , Number et String , elles deviennent des objets. L'opérateur instanceof ne fonctionne que pour les objets (c'est pourquoi il renvoie false pour les valeurs primitives):

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

Comme vous pouvez le voir, typeof et instance de ne suffisent pas pour vérifier si une valeur est un booléen, un nombre ou une chaîne - typeof ne fonctionne que pour les booléens primitifs, les nombres et les chaînes; et instanceof ne fonctionne pas pour les booléens, les nombres et les chaînes primitifs.

Heureusement, il existe une solution simple à ce problème. L'implémentation par défaut de toString (c'est-à-dire telle qu'elle est définie de manière native sur Object.prototype.toString ) renvoie la propriété interne [[Class]] des deux. valeurs et objets primitifs:

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 propriété interne [[Class]] d'une valeur est beaucoup plus utile que la typeof de la valeur. Nous pouvons utiliser Object.prototype.toString pour créer notre propre version (plus utile) de l'opérateur typeof comme suit:

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

J'espère que cet article vous a aidé. Pour en savoir plus sur les différences entre les primitives et les objets encapsulés, lisez le billet suivant: > La vie secrète des primitifs JavaScript & nbsp; Primitives

Vous pouvez utiliser la propriété du constructeur:

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

vous pouvez l'utiliser, cela fonctionnera pour les deux cas comme

  1. var text = "toto"; // typeof fonctionnera

  2. String text = new String ("toto"); // instanceof fonctionnera

Je pense avoir mis au point une solution viable:

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

Ceci est défini dans la spécification ECMAScript Section 7.3.19 Étape 3 : Si le type (O) n'est pas un objet, renvoyez false.

En d'autres termes, si le Obj dans Obj instance of Callable n'est pas un objet, le instance of sera court-circuité à . false directement.

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

Renvoie une représentation sous forme de chaîne de instance de (nom du constructeur)

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"

Pour moi, la confusion causée par

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

So " str " istanceof String doit renvoyer true , car comment istanceof fonctionne comme ci-dessous:

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

Les résultats de l'expression n ° 1 et n ° 2 sont contradictoires. Par conséquent, l'un d'entre eux doit être erroné.

# 1 est faux

Je découvre que cela est dû à la propriété non standard de __ proto __ . Vous devez donc utiliser la propriété standard: Object.getPrototypeOf

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

Désormais, il n'y a plus de confusion entre l'expression n ° 2 et n ° 3

.

Ou vous pouvez simplement créer votre propre fonction comme suit:

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

utilisation:

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

Ceux-ci doivent tous deux renvoyer la valeur true.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top