javascript - Warum gibt instanceof für einige Literale false zurück?
"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 entsprechen...
[0,1] instanceof Array //=> true
{0:1} instanceof Object //=> true
Warum tun das nicht alle? Oder warum tun sie alle nicht?
Und, wofür sind sie dann ein Beispiel?
Es ist dasselbe in FF3, IE7, Opera und Chrome. Also ist es zumindest konsistent.
Antwort #1
Primitive Typen sind eine andere Art von Typ als Objekte, die innerhalb von Javascript erstellt werden. Aus den Mozilla API-Dokumenten:
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 keinen Weg finden, primitive Typen mit Code zu konstruieren, vielleicht ist es nicht möglich. Wahrscheinlich ist das der Grund, warum Leute typeof "foo" === "string" anstelle von instanceof verwenden.
Eine einfache Möglichkeit, sich solche Dinge zu merken, 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 Gegenteil.
Antwort #2
Ich benutze:
function isString(s) {
return typeof(s) === 'string' || s instanceof String;
}
Weil in JavaScript Zeichenketten Literale oder Objekte sein können.
Antwort #3
In JavaScript ist alles ein Objekt (oder kann zumindest wie ein Objekt behandelt werden), außer primitiven Werten (Booleans, null, Zahlen, Strings und dem 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 sehen können, gelten Objekte, Arrays und der Wert null alle als Objekte (null ist eine Referenz auf ein Objekt, das nicht existiert). Funktionen werden unterschieden, weil sie eine spezielle Art von aufrufbaren Objekten sind. Sie sind jedoch immer noch Objekte.
Andererseits sind die Literale true, 0, "" und undefined keine Objekte. Sie sind primitive Werte in JavaScript. Booleans, Zahlen und Strings haben jedoch ebenfalls Konstruktoren Boolean, Number und String, die ihre jeweiligen Primitivwerte umhüllen, 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, wenn sie jeweils innerhalb der Konstruktoren Boolean, Number und String eingeschlossen werden, zu Objekten. Der Operator instanceof funktioniert nur bei Objekten (deshalb gibt er für primitive Werte false zurück):
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 Sie sehen können, sind sowohl typeof als auch instanceof unzureichend, um zu testen, ob ein Wert ein Boolean, eine Zahl oder ein String ist - typeof funktioniert nur für primitive Booleans, Zahlen und Strings; und instanceof funktioniert nicht für primitive Booleans, Zahlen und Strings.
Glücklicherweise gibt es eine einfache Lösung für dieses Problem. Die Standardimplementierung von toString (also so, wie sie nativ auf Object.prototype.toString definiert ist) gibt die interne [[Class]]-Eigenschaft sowohl von primitiven Werten als auch von Objekten zurück:
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]
Die interne [[Class]]-Eigenschaft eines Wertes ist viel nützlicher als der typeof-Typ des Wertes. Wir können Object.prototype.toString verwenden, um unsere eigene (nützlichere) Version des typeof-Operators wie folgt zu erstellen:
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 war hilfreich. Um mehr über die Unterschiede zwischen Primitiven und verpackten Objekten zu erfahren, lesen Sie den folgenden Blogbeitrag: Das geheime Leben der JavaScript-Primitiven
Antwort #4
Sie können die Konstruktor-Eigenschaft verwenden:
'foo'.constructor == String // returns true
true.constructor == Boolean // returns true
Antwort #5
typeof(text) === 'string' || text instanceof String;
du kannst dies verwenden, es wird für beide Fälle funktionieren, da
var text="foo";/typeof wird funktionierenString text= new String("foo");/instanceof wird funktionieren
