"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 font-ils pas tous pas?
Et de quoi s'agit-il alors?
C'est la même chose dans FF3, IE7, Opera et Chrome. Donc, au moins c'est cohérent.
Quelques manqués.
12.21 instanceof Number //=> false
/foo/ instanceof RegExp //=> true
Les primitives sont d'un type différent des objets créés à partir de Javascript. À partir de la documentation de l'API 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 pourquoi les gens utilisent typeof "foo" === "string"
au lieu de instanceof
.
Un moyen facile 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 l'autre chose.
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 (booleans, null, numbers, strings 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 considérés comme des objets (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, ils sont toujours des objets.
D'autre part, les littéraux true
, 0
, ""
Et undefined
ne sont pas des objets. Ce sont des valeurs primitives en JavaScript. Cependant, les booléens, les nombres et les chaînes ont également les constructeurs Boolean
, Number
et String
respectivement, qui encapsulent leurs primitives respectives pour offrir 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 voir lorsque des valeurs primitives sont encapsulées dans les constructeurs Boolean
, Number
et String
, elles deviennent respectivement 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 constater, typeof
et instanceof
ne suffisent pas pour déterminer si une valeur est un booléen, un nombre ou une chaîne - typeof
ne fonctionne que pour les booléens, les nombres et les chaînes primitifs. ; et instanceof
ne fonctionne pas pour les booléens primitifs, les nombres et les chaînes.
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 valeurs et des 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
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 a aidé. Pour en savoir plus sur les différences entre les primitives et les objets encapsulés, lisez le billet de blog suivant: La vie secrète des primitives JavaScript
Vous pouvez utiliser la propriété 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
var text="foo";
// typeof fonctionnera
String text= new String("foo");
// 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 Step : If Type(O) is not Object, return false.
En d'autres mots, si le Obj
dans Obj instanceof Callable
n'est pas un objet, le instanceof
court-circuitera directement à false
.