342 votes

Pourquoi instanceof retourne false pour certains littéraux ?

<pre><code></code><p>Les littéraux de tableau et correspondance de littéraux d’objet...</p><pre><code></code></pre><p><em>aucun</em> d'entre eux ?<br> <code></code>?</p><p>C’est la même chose dans FF3, IE7, Opera et Chrome. Ainsi, au moins c’est cohérent. ;)</p><p><hr><p>Manqué quelques-uns. ;)</p><pre><code></code></pre></pre>

519voto

John Millikin Points 86775

Les littéraux sont un autre type d'objet que des objets créés à partir de Javascript. À partir de la 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)

Je ne peux pas trouver un moyen de construire littérale avec des types de code, peut-être qu'il n'est pas possible. C'est probablement pourquoi les gens utilisent des typeof "foo" === "string" au lieu de instanceof.

Un moyen facile de se rappeler ce genre de choses est à vous demander "je me demande ce qui serait sain et plus facile à apprendre"? Quelle que soit la réponse est, Javascript n'est autre chose.

127voto

axkibe Points 661

J’utilise :

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

77voto

Aadit M Shah Points 17951

En JavaScript, tout est un objet (ou au moins peuvent être traités comme un objet). Le seul non-objets sont primitives des booléens, des nombres, des chaînes et la valeur undefined:

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 objets, 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 sont d'un type spécial de appelable objets. Cependant, ils sont encore des objets.

D'autre part les littéraux true, 0, "" et undefined ne sont pas des objets. Ils sont des valeurs primitives en JavaScript. Cependant, des booléens, des nombres et des chaînes ont aussi des constructeurs Boolean, Number et String respectivement, ce qui l'envelopper de ses respectifs des primitives pour fournir des fonctionnalités supplémentaires:

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 enveloppés à l'intérieur de l' Boolean, Number et String constructeurs, respectivement, ils deviennent des objets. L' instanceof opérateur ne fonctionne que pour les objets (c'est pourquoi il retourne 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 les deux typeof et instanceof sont insuffisantes pour tester si une valeur est un booléen, un nombre ou une chaîne - typeof fonctionne uniquement pour les primitives des booléens, des nombres et des chaînes; instanceof ne fonctionne pas pour les primitives des booléens, des nombres et des chaînes.

Heureusement il existe une solution simple à ce problème. L'implémentation par défaut de toString (c'est à dire qu'il est nativement définie sur Object.prototype.toString) retourne l'interne [[Class]] de la propriété de deux valeurs primitives et les objets:

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]

L'interne [[Class]] de biens dont la valeur est beaucoup plus utile que l' typeof la valeur. On peut utiliser Object.prototype.toString de créer notre propre (plus utile) version de l' typeof opérateur 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

Espère que cet article vous a aidé. Pour en savoir plus sur les différences entre les primitives et enveloppé objets de lire le blog suivant: La Vie Secrète de JavaScript Primitives

43voto

user144049 Points 181

Vous pouvez utiliser la propriété constructor :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X