いくつかのリテラルでinstanceofがfalseを返すのはなぜですか?
-
03-07-2019 - |
質問
"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
配列リテラルとオブジェクトリテラルが一致...
[0,1] instanceof Array //=> true
{0:1} instanceof Object //=> true
なぜそれらすべてではないのですか?または、なぜ彼らはすべて ではないのですか?
そして、それらのインスタンスは何ですか?
FF3、IE7、Opera、Chromeでも同じです。したがって、少なくとも一貫性があります。
いくつか欠落しました。
12.21 instanceof Number //=> false
/foo/ instanceof RegExp //=> true
解決
プリミティブは、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"を使用する理由です。 ===
。 instanceof
の代わりに" string"
このようなことを覚える簡単な方法は、「正気で習得しやすいものは何だろう」と自問することです。答えが何であれ、Javascriptは他のことを行います。
他のヒント
使用:
function isString(s) {
return typeof(s) === 'string' || s instanceof String;
}
JavaScriptでは、文字列はリテラルまたはオブジェクトにできるため。
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
は存在しないオブジェクトへの参照です)。関数は、呼び出し可能オブジェクトの特別なタイプであるため区別されます。ただし、それらはまだオブジェクトです。
一方、リテラル true
、 0
、""
および undefined
はオブジェクトではありません。 JavaScriptのプリミティブな値です。ただし、ブール値、数値、および文字列には、それぞれのプリミティブをラップして追加機能を提供するコンストラクター Boolean
、 Number
、および String
もあります。
console.log(typeof new Boolean(true)); // object
console.log(typeof new Number(0)); // object
console.log(typeof new String("")); // object
プリミティブ値が Boolean
、 Number
、および 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]]
プロパティは、値の typeof
よりもはるかに便利です。次のように、 Object.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の秘密の生活  Primitives
コンストラクタープロパティを使用できます:
'foo'.constructor == String // returns true
true.constructor == Boolean // returns true
typeof(text) === 'string' || text instanceof String;
これを使用できます。どちらの場合でも機能します
-
var text =" foo&quot ;;
// typeofは動作します -
String text = new String(" foo");
// instanceofは機能します
実行可能なソリューションを思いついたと思います:
Object.getPrototypeOf('test') === String.prototype //true
Object.getPrototypeOf(1) === String.prototype //false
これは、ECMAScript仕様で定義されていますセクション7.3.19ステップ3 : Type(O)がObjectでない場合、falseを返します。
つまり、 Obj instanceof Callable
の Obj
がオブジェクトでない場合、 instanceof
はに短絡しますfalse
直接。
https://www.npmjs.com/package/typeof
instanceof
(コンストラクター名)の文字列表現を返します
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"
私にとっての混乱
"str".__proto__ // #1
=> String
だから" str" istanceof文字列
は、 true
を返す必要があります。これは、istanceofが以下のように機能するためです。
"str".__proto__ == String.prototype // #2
=> true
式#1 と#2 の結果は互いに矛盾するため、いずれかが間違っているはずです。
#1は間違っています
__ proto __
が原因であることがわかったため、標準のプロパティを使用します: Object.getPrototypeOf
Object.getPrototypeOf("str") // #3
=> TypeError: Object.getPrototypeOf called on non-object
式#2 と#3
の間に混乱はありません。または、次のように独自の関数を作成することもできます。
function isInstanceOf(obj, clazz){
return (obj instanceof eval("("+clazz+")")) || (typeof obj == clazz.toLowerCase());
};
使用法:
isInstanceOf('','String');
isInstanceOf(new String(), 'String');
これらは両方ともtrueを返す必要があります。