313
"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

配列リテラルとオブジェクトリテラルは一致します...

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

なぜそれらすべてをしないのですか?または、なぜそれらはすべてではないのですか?
そして、それらは何のインスタンスですか?

FF3、IE7、Opera、Chromeでも同じです。したがって、少なくとも一貫性があります。

4

10 に答える 10

479

プリミティブは、Javascript 内から作成されたオブジェクトとは異なる種類の型です。Mozilla API ドキュメントから:

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

コードでプリミティブ型を構築する方法が見つかりません。おそらく不可能です。typeof "foo" === "string"これがおそらく、人々がの代わりに を使用する理由ですinstanceof

このようなことを覚える簡単な方法は、「正気で学びやすいものは何だろうか」と自問することです。答えが何であれ、Javascript は別のことを行います。

于 2008-10-15T04:54:52.020 に答える
118

私が使う:

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

JavaScript では、文字列はリテラルまたはオブジェクトになる可能性があるためです。

于 2011-10-14T19:38:48.857 に答える
70

JavaScript では、プリミティブ(ブール値、null、数値、文字列、および値undefined(および 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

ご覧のとおり、オブジェクト、配列、および値nullはすべてオブジェクトと見なされます (nullは存在しないオブジェクトへの参照です)。関数は、特別なタイプの呼び出し可能なオブジェクトであるため、区別されます。しかし、それらはまだオブジェクトです。

一方、リテラルtrue0""およびundefinedはオブジェクトではありません。これらは JavaScript のプリミティブ値です。ただし、ブール値、数値、および文字列にもコンストラクターBooleanNumberありString、それぞれのプリミティブをラップして追加機能を提供します。

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

ご覧のとおり、プリミティブ値がBooleanNumberおよびStringコンストラクター内にそれぞれラップされると、それらはオブジェクトになります。instanceof演算子はオブジェクトに対してのみ機能します (これが、プリミティブ値に対して返される理由ですfalse)。

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

ご覧のとおり、値がブール値、数値、または文字列であるかどうかをテストするには、typeofとの両方instanceofが不十分typeofです。プリミティブなブール値、数値、および文字列に対してのみ機能します。プリミティブブール値、数値、および文字列では機能しinstanceofません。

幸いなことに、この問題には簡単な解決策があります。のデフォルトの実装toString(つまり でネイティブに定義されている) は、プリミティブ値とオブジェクトの両方Object.prototype.toStringの内部プロパティを返します。[[Class]]

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]

値の内部[[Class]]プロパティは、値よりもはるかに便利ですtypeofObject.prototype.toString次のように、独自の (より便利な) バージョンのtypeofオペレーターを作成するために使用できます。

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

この記事がお役に立てば幸いです。プリミティブとラップされたオブジェクトの違いの詳細については、次のブログ投稿を参照してください: JavaScript プリミティブの秘密の生活

于 2013-08-05T11:35:25.690 に答える
39

コンストラクター プロパティを使用できます。

'foo'.constructor == String // returns true
true.constructor == Boolean // returns true
于 2009-07-26T23:10:50.880 に答える
-2

私にとって、混乱は

"str".__proto__ // #1
=> String

instanceofが以下のように機能するため、"str" istanceof String返される必要がありtrueます。

"str".__proto__ == String.prototype // #2
=> true

#1#2の結果は互いに競合するため、どちらかが間違っているはずです。

#1は間違っている

is 非標準プロパティが原因であることがわかった__proto__ので、標準プロパティを使用します。Object.getPrototypeOf

Object.getPrototypeOf("str") // #3
=> TypeError: Object.getPrototypeOf called on non-object

これで、式#2#3の間に混乱はなくなりました

于 2015-01-12T09:59:50.023 に答える
-8

または、次のように独自の関数を作成することもできます。

function isInstanceOf(obj, clazz){
  return (obj instanceof eval("("+clazz+")")) || (typeof obj == clazz.toLowerCase());
};

利用方法:

isInstanceOf('','String');
isInstanceOf(new String(), 'String');

これらは両方ともtrueを返すはずです。

于 2010-02-16T16:54:35.380 に答える