Warum gibt instanceof für einige Literale falsch zurück?

Lesezeit: 6 Minuten

Warum gibt instanceof fur einige Literale falsch zuruck
Jonathan Lonowski

"foo" instanceof String //=> false
"foo" instanceof Object //=> false

true instanceof Boolean //=> false
true instanceof Object //=> false
false instanceof Boolean //=> false
false instanceof Object //=> false

12.21 instanceof Number //=> false
/foo/ instanceof RegExp //=> true

// the tests against Object really don't make sense

Array-Literale und Objekt-Literale stimmen überein…

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

Warum nicht alle? Oder warum nicht alle nicht?
Und wovon sind sie dann ein Beispiel?

Dasselbe gilt für FF3, IE7, Opera und Chrome. So ist es zumindest konsequent.

Warum gibt instanceof fur einige Literale falsch zuruck
John Millikin

Primitive sind eine andere Art von Typ als Objekte, die in Javascript erstellt wurden. Von dem Mozilla-API-Dokumentation:

var color1 = new String("green");
color1 instanceof String; // returns true
var color2 = "coral";
color2 instanceof String; // returns false (color2 is not a String object)

Ich kann keine Möglichkeit finden, primitive Typen mit Code zu konstruieren, vielleicht ist es nicht möglich. Dies ist wahrscheinlich der Grund, warum die Leute verwenden typeof "foo" === "string" anstatt instanceof.

Eine einfache Möglichkeit, sich an solche Dinge zu erinnern, besteht darin, sich zu fragen: “Ich frage mich, was vernünftig und leicht zu lernen wäre”? Was auch immer die Antwort ist, Javascript macht das andere.

  • Jeder Tag mit einem neuen Grund, JavaScript zu hassen, ist ein guter Tag. Ich weiß, es ist längst überfällig, aber ich danke dir für diesen Beitrag.

    – tonedzwiedz

    3. September 2012 um 22:35 Uhr

  • Ihre Terminologie ist falsch. Das Wort „Literal“ bezieht sich auf eine Syntax zum Erstellen von Daten ohne Verwendung eines Konstruktors. Es bezieht sich nicht auf die resultierenden Daten. Literale Syntax kann verwendet werden, um sowohl Objekte als auch Nicht-Objekte zu erstellen. Der korrekte Begriff ist “Primitive”, der sich auf Nicht-Objektdaten bezieht. Einige Daten haben sowohl primitive als auch Objektdarstellungen. String ist einer dieser Datentypen.

    – Grauzustand kommt

    4. September 2012 um 0:35 Uhr

  • Zu Ihrer Information, Sie können Primitive ohne wörtliche Syntax erstellen. (new String()).valueOf();

    – Grauzustand kommt

    4. September 2012 um 0:38 Uhr

  • Beachten Sie, dass typeof foo === 'string' ist nicht genug: siehe Antwort von axkibe.

    – Bryan Larsen

    16. Mai 2013 um 17:46 Uhr

  • Außerdem typeof new String('') kehrt zurück "object"

    – transang

    23. August 2018 um 9:18 Uhr

1646117708 237 Warum gibt instanceof fur einige Literale falsch zuruck
axkibe

Ich benutze:

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

Denn in JavaScript können Strings Literale oder Objekte sein.

  • Ich habe übrigens etwas Kürzeres gefunden. function isString(s) { return s.constructor === String; } Funktioniert für Literale und String-Objekte (zumindest in V8)

    – axkibe

    6. Dezember 2011 um 13:05 Uhr


  • Ich verwende jQuery.type(s) === ‘string’ (api.jquery.com/jquery.type), jQuery.isArray(), jQuery.isFunction(), jQuery.isNumeric() wenn es möglich ist.

    – Iwan Samygin

    8. August 2014 um 7:21 Uhr

  • @axkibe, während du Recht hast, ist es nicht annähernd so performant als typeof.

    – Qix – MONICA WURDE MISSHANDELT

    9. April 2015 um 23:42 Uhr

  • Sie können typeof “?” == String.name.toLowerCase() [but why is [] Instanz von Array ?]

    – QuentinUK

    14. Mai 2015 um 18:23 Uhr


  • Dasselbe Problem besteht für boolesche Werte: true instanceof Boolean => false und doch typeof true => boolean … Was auch. stackoverflow.com/a/4745303/362042

    – Dakota

    4. September 2015 um 2:13 Uhr

1646117709 268 Warum gibt instanceof fur einige Literale falsch zuruck
Aadit M Shah

In JavaScript ist alles ein Objekt (oder kann zumindest als Objekt behandelt werden), außer Primitive (Booleans, Null, Zahlen, Strings und der Wert undefined (und Symbol in 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

Wie Sie Objekte, Arrays und den Wert sehen können null werden alle als Objekte betrachtet (null ist ein Verweis auf ein Objekt, das nicht existiert). Funktionen werden unterschieden, weil sie eine besondere Art von sind abrufbar Objekte. Sie sind jedoch immer noch Objekte.

Andererseits die Literale true, 0, "" und undefined sind keine Gegenstände. Sie sind primitive Werte in JavaScript. Boolesche Werte, Zahlen und Strings haben jedoch auch Konstruktoren Boolean, Number und String die ihre jeweiligen Grundelemente umschließen, um zusätzliche Funktionalität bereitzustellen:

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

Wie Sie sehen können, werden primitive Werte in die eingeschlossen Boolean, Number und String Konstruktoren bzw. sie werden zu Objekten. Die instanceof -Operator funktioniert nur für Objekte (weshalb er zurückkehrt false für primitive Werte):

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

Wie man beides sieht typeof und instanceof reichen nicht aus, um zu testen, ob ein Wert ein boolescher Wert, eine Zahl oder ein String ist – typeof funktioniert nur für primitive boolesche Werte, Zahlen und Strings; und instanceof funktioniert nicht für primitive boolesche Werte, Zahlen und Strings.

Glücklicherweise gibt es eine einfache Lösung für dieses Problem. Die Standardimplementierung von toString (dh wie es nativ auf definiert ist Object.prototype.toString) gibt die interne zurück [[Class]] Eigenschaft von primitiven Werten und Objekten:

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]

Das Innere [[Class]] Eigenschaft eines Wertes ist viel nützlicher als die typeof der Wert. Wir können benutzen Object.prototype.toString um unsere eigene (nützlichere) Version von zu erstellen typeof Betreiber wie folgt:

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

Hoffe, dieser Artikel hat geholfen. Um mehr über die Unterschiede zwischen Primitiven und umschlossenen Objekten zu erfahren, lesen Sie den folgenden Blogbeitrag: Das geheime Leben von JavaScript-Primitiven

  • +1, obwohl null ist ein primitiver Wert auch (nur die typeof Betreiber ist verwirrend)

    – Bergi

    7. August 2013 um 10:13 Uhr

Sie können die Konstruktoreigenschaft verwenden:

'foo'.constructor == String // returns true
true.constructor == Boolean // returns true

1646117709 421 Warum gibt instanceof fur einige Literale falsch zuruck
saurabhgoyal795

 typeof(text) === 'string' || text instanceof String; 

Sie können dies verwenden, es funktioniert für beide Fälle

  1. var text="foo"; // typeof wird funktionieren

  2. String text= new String("foo"); // instanceof wird funktionieren

1646117709 947 Warum gibt instanceof fur einige Literale falsch zuruck
HKTonyLee

Dies ist in der ECMAScript-Spezifikation definiert Abschnitt 7.3.19 Schritt 3: If Type(O) is not Object, return false.

Mit anderen Worten, wenn die Obj in Obj instanceof Callable ist kein Objekt, das instanceof wird kurzschließen false direkt.

Ich glaube, ich habe eine brauchbare Lösung gefunden:

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

897820cookie-checkWarum gibt instanceof für einige Literale falsch zurück?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy