オブジェクトがコンストラクターのインスタンスであるかどうかを確認するために、instanceof 演算子が使用されることがわかっています。 true が返されるさまざまなシナリオを以下に示します。
1. オブジェクト obj が new Constructor を通じて作成され、obj instanceof Constructor が true になります。
次のようにコードをコピーします。
関数 人(n, a) {
this.name = n;
this.age = a;
}
var p = 新しい人物('ジョン・バッカス', 82);
console.log(p 人のインスタンス); // true
2. 継承関係がある場合、サブクラスと親クラスのinstanceofもtrueを返します。
次のようにコードをコピーします。
関数 A(){}
関数 B(){}
B.prototype = new A() // B は A を継承します。
var b = 新しい B();
console.log(b インスタンスオブ A); // true
3. Object はルート クラスであるため、他のすべてのカスタム クラスはそれを継承するため、コンストラクターの instanceof Object は true を返します。
次のようにコードをコピーします。
関数 A() {}
var a = 新しい A();
console.log(オブジェクトのインスタンス); // true
var str = 新しい文字列('hello');
console.log(str オブジェクトのインスタンス); // true
var num = 新しい数値(1);
console.log(オブジェクトのインスタンス数); // true
コンストラクター自体でも
次のようにコードをコピーします。
関数 A() {}
console.log(オブジェクトのインスタンス); // true
console.log(String オブジェクトのインスタンス); // true
console.log(オブジェクトのインスタンス数); // true
4. すべてのコンストラクターinstanceof Functionはtrueを返します。
次のようにコードをコピーします。
関数 A() {}
console.log(関数のインスタンス); // true
console.log(String 関数のインスタンス); // true
console.log(関数のインスタンス数); // true
上記の 4 つの点を 1 つの文に要約します。インスタンスが特定のクラスまたはそのサブクラスによって作成された場合、instanceof は true を返します。または、特定のコンストラクターのプロトタイプがオブジェクト obj の内部プロトタイプ チェーンに存在する場合は、true が返されます。つまり、instanceof の結果はコンストラクター自体とは直接の関係がありません。これは多くの言語で一般的です。
クラス Person は Java で定義されており、インスタンス p は Person と Object の両方に対して true を返します。
次のようにコードをコピーします。
クラス人 {
パブリック文字列名。
公的整数年齢。
人 (文字列 n, int a) {
this.name = 名前;
this.age = a;
}
public static void main(String[] args) {
人 p = 新しい人("ジョン・バッカス", 82);
System.out.println(p 人のインスタンス); // true
System.out.println(p オブジェクトのインスタンス); // true
}
}
Java に継承関係がある場合、サブクラスの親クラスのインスタンスも true を返します。
次のようにコードをコピーします。
// 親クラス
クラス人 {
パブリック文字列名。
公的整数年齢。
人 (文字列 n, int a) {
名前 = 名前;
年齢 = a;
}
}
// サブクラス
public class Man は Person{ を拡張します
公立弦楽大学。
Man(String n, int a, String s) {
スーパー(n, a);
大学 = s;
}
public static void main(String[] args) {
Man mm = new Man("John Resig", 29, "PKU");
System.out.println(mm インスタンスオブマン); // true
System.out.println(mm インスタンスオブ パーソン); // これも true
}
}
これを知っていると、JS での次のパフォーマンスは驚くべきことではありません。
次のようにコードをコピーします。
// 2 つのコンストラクターを定義する
関数 A(){}
関数 B(){}
A.プロトタイプ = B.プロトタイプ = {a: 1};
//異なるコンストラクターの 2 つのインスタンスをそれぞれ作成します
var a = 新しい A();
var b = 新しい B();
console.log(B のインスタンス); // true
console.log(b インスタンスオブ A); // true
a と b がそれぞれ A と B で作成されていることがわかりますが、ainstanceofB と binstanceofA はどちらも true です。つまり、 a はコンストラクター B で作成されませんが、それでも true を返します。 B.prototype は a の内部プロトタイプ チェーンに存在するためです。
JS の動的言語特性により、プロトタイプは実行時に変更される可能性があるため、次のコードが false を返すことは驚くべきことではありません。 A.prototype は a の内部プロトタイプ チェーンに存在しなくなったため、チェーンは中断されます。
次のようにコードをコピーします。
関数 A(){}
var a = 新しい A();
A.prototype = {}; // プロトタイプを動的に変更します。これは、プロトタイプを作成した後に行う必要があることに注意してください。
console.log(A のインスタンス); // false
これを書くと、上で要約した最初のポイントも壊れることに注意してください。オブジェクト obj は new Constructor を通じて作成され、obj instanceof Constructor は true になります。
実際、ECMAScript 標準 (5.1 に準拠) では、instanceof の内部実装はコンストラクターの内部メソッド [[HasInstance]] を呼び出します。これは次のように説明されます。
F が関数オブジェクトの場合、F(V) が実行されると、次のステップが発生します。
1.instanceof の左オペランド V がオブジェクト型でない場合は、直接 false を返します。
次のようにコードをコピーします。
var a、b = 1、c = true、d = 'hello';
console.log(a instanceof Object); // ここでは値は未定義です
console.log(b オブジェクトのインスタンス); // false
console.log(c オブジェクトのインスタンス); // false
console.log(d オブジェクトのインスタンス); // false
2/3. コンストラクター F のプロトタイプ属性を取得します。オブジェクト型でない場合は、TypeError 例外をスローする必要があります。
次のようにコードをコピーします。
関数 A(){}
A.prototype = 1; // A のプロトタイプを非オブジェクト型に設定します。
var a = 新しい A();
console.log(A のインスタンス);
各ブラウザによってスローされる例外プロンプトは異なります。
Firefox18:
Chrome24:
サファリ6:
オペラ12:
IE10:
4. 次のロジックを継続的に実行します。V を内部プロトタイプの V に設定し、V が null の場合は false を返し、V と O の両方が同じオブジェクトを指している場合は true を返します。