it-swarm.com.de

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

// 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?

Dies ist auch in FF3, IE7, Opera und Chrome der Fall. Zumindest ist es konsistent.


Verpasste ein paar.

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

Primitive sind andere Typen als Objekte, die mit Javascript erstellt wurden. 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 keine Möglichkeit finden, primitive Typen mit Code zu konstruieren, vielleicht ist das nicht möglich. Dies ist wahrscheinlich der Grund, warum die Leute typeof "foo" === "string" anstelle von instanceof.

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

385
John Millikin

Ich benutze:

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

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

93
axkibe

In JavaScript ist alles ein Objekt (oder kann zumindest als Objekt behandelt werden), außer Grundelemente (Boolesche Werte, Nullen, Zahlen, Zeichenfolgen und der Wert undefined (und das 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, werden alle Arrays und der Wert null als Objekte betrachtet (null ist eine Referenz auf ein Objekt, das nicht existiert). Funktionen zeichnen sich dadurch aus, dass es sich um einen speziellen Typ von aufrufbaren Objekten handelt. Sie sind jedoch immer noch Objekte.

Andererseits sind die Literale true, 0, "" Und undefined keine Objekte. Sie sind Grundwerte in JavaScript. Boolesche Werte, Zahlen und Zeichenfolgen 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, werden Grundwerte zu Objekten, wenn sie in die Konstruktoren Boolean, Number und String eingeschlossen werden. Der Operator instanceof funktioniert nur für Objekte (weshalb er false für Grundwerte 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 sehen, reichen sowohl typeof als auch instanceof nicht aus, um zu testen, ob ein Wert ein Boolescher Wert, eine Zahl oder eine Zeichenfolge ist - typeof funktioniert nur für primitive Boolesche Werte, Zahlen und Zeichenfolgen ; und instanceof funktioniert nicht für primitive Boolesche Werte, Zahlen und Zeichenfolgen.

Zum Glück gibt es eine einfache Lösung für dieses Problem. Die Standardimplementierung von toString (d. H. Wie sie nativ in Object.prototype.toString Definiert ist) gibt die interne Eigenschaft [[Class]] Sowohl von Grundwerten 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 Eigenschaft [[Class]] Eines Werts ist viel nützlicher als die Eigenschaft typeof des Werts. Mit Object.prototype.toString Können wir unsere eigene (nützlichere) Version des Operators typeof wie folgt 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 hat geholfen. Um mehr über die Unterschiede zwischen Primitiven und verpackten Objekten zu erfahren, lesen Sie den folgenden Blog-Beitrag: Das geheime Leben von JavaScript-Primitiven

56
Aadit M Shah

Sie können die Konstruktoreigenschaft verwenden:

'foo'.constructor == String // returns true
true.constructor == Boolean // returns true
31
user144049
 typeof(text) === 'string' || text instanceof String; 

sie können dies verwenden, es funktioniert in beiden Fällen als

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

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

6
saurabhgoyal795

Ich glaube, ich habe eine tragfähige Lösung gefunden:

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

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

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

1
HKTonyLee