Warum Instanceof return false für einige Literale?
-
03-07-2019 - |
Frage
"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
Array Literale und Objektliterale Spiel ...
[0,1] instanceof Array //=> true
{0:1} instanceof Object //=> true
Warum nicht alle von ihnen? Oder warum nicht sie alle nicht ?
Und was sind sie eine Instanz, dann?
Es ist das gleiche in FF3, IE7, Opera und Chrome. Also, zumindest ist es konsistent.
Missed einige zu nennen.
12.21 instanceof Number //=> false
/foo/ instanceof RegExp //=> true
Lösung
Primitives sind eine andere Art von Typ als Objekte aus Javascript erstellt. Von der 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 nicht möglich, es ist. Dies ist wahrscheinlich, warum die Leute typeof "foo" === "string"
anstelle von instanceof
.
Eine einfache Möglichkeit, solche Dinge zu erinnern ist, fragt sich: „Ich frage mich, was gesund und leicht zu erlernen wäre“? Was auch immer die Antwort ist, Javascript funktioniert die andere Sache.
Andere Tipps
ich benutze:
function isString(s) {
return typeof(s) === 'string' || s instanceof String;
}
Da in JavaScript-Strings können Literale oder Objekte sein.
In JavaScript ist alles ein Objekt (oder zumindest als ein Objekt behandelt werden), mit Ausnahme von Primitiven (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 sehen können, Arrays und den Wert null
sind alle betrachteten Objekte (null
ist ein Verweis auf ein Objekt, das nicht existiert). Funktionen unterscheiden, weil sie eine besondere Art von aufrufbar Objekten. Allerdings sind sie immer noch Objekte.
Auf der anderen Seite der Literale true
, 0
, ""
und undefined
sind keine Objekte. Sie sind primitive Werte in JavaScript. Allerdings booleans, Zahlen und Strings haben auch Konstrukteure Boolean
, Number
und String
jeweils die wickeln ihre jeweiligen Grundelemente bieten Funktionen hinzugefügt:
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, wenn primitive Werte innerhalb der Boolean
gewickelt sind, Number
und String
Konstrukteuren bzw. sie Objekte werden. Der instanceof
Operator funktioniert nur für Objekte (weshalb es false
für primitive Werte zurückgibt):
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 beide typeof
und instanceof
reicht nicht sehen können zu prüfen, ob ein Wert ein boolean ist, eine Zahl oder ein String - typeof
funktioniert nur für primitive booleans, Zahlen und Strings; und instanceof
funktioniert nicht für primitive booleans, Zahlen und Strings.
Zum Glück gibt es eine einfache Lösung für dieses Problem. Die Standardimplementierung von toString
(das heißt, wie es nativ auf Object.prototype.toString
definiert ist) gibt die interne [[Class]]
Eigenschaft sowohl primitive Werte und Objekte:
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 Wert ist viel nützlicher als die typeof
der Wert. Wir können Object.prototype.toString
verwenden unsere eigene (nützliche) 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
Hope dieser Artikel geholfen. Um mehr über die Unterschiede zwischen den Primitiven und schlangen Objekte kennen lesen Sie die folgende Blog-Post: Das geheime Leben der JavaScript Primitives
Sie können Konstruktor Eigenschaft verwenden:
'foo'.constructor == String // returns true
true.constructor == Boolean // returns true
typeof(text) === 'string' || text instanceof String;
Sie diese nutzen können, wird es für beide Fall als
arbeiten-
var text="foo";
// typeof funktioniert -
String text= new String("foo");
// instanceof wird funktionieren
Ich glaube, ich habe mit einer tragfähigen Lösung zu kommen:
Object.getPrototypeOf('test') === String.prototype //true
Object.getPrototypeOf(1) === String.prototype //false
Dies ist in dem ECMAScript-Spezifikation Abschnitt 7.3.19 Schritt 3: If Type(O) is not Object, return false.
Mit anderen Worten, wenn die Obj
in Obj instanceof Callable
kein Objekt ist, wird die instanceof
Kurzschluss direkt an false
.
https://www.npmjs.com/package/typeof
Gibt eine String-Darstellung von instanceof
(der Konstrukteurs-Namen)
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"
Für mich ist die Verwirrung, die durch
verursacht"str".__proto__ // #1
=> String
So "str" istanceof String
sollte true
zurück, weil, wie istanceof funktioniert wie folgt:
"str".__proto__ == String.prototype // #2
=> true
Die Ergebnisse des Ausdrucks # 1 und # 2 sich in Konflikt steht, so sollte es einer von ihnen falsch sein.
# 1 ist falsch
ich herausgefunden habe, dass es durch die __proto__
Nicht-Standard-Eigenschaft ist, so verwenden Sie den Standard ein: Object.getPrototypeOf
Object.getPrototypeOf("str") // #3
=> TypeError: Object.getPrototypeOf called on non-object
Jetzt gibt es keine Verwirrung zwischen Ausdruck # 2 und # 3
Oder Sie können einfach Ihre eigene Funktion wie so machen:
function isInstanceOf(obj, clazz){
return (obj instanceof eval("("+clazz+")")) || (typeof obj == clazz.toLowerCase());
};
Nutzung:
isInstanceOf('','String');
isInstanceOf(new String(), 'String');
Diese sollten sowohl return true.