メソッド紹介
インスタンスオブとは?
コンストラクターのプロトタイプ属性がインスタンス オブジェクトのプロトタイプ チェーンに現れるかどうかを検出するために使用されます。
構文: object instanceofコンストラクター
オブジェクト: インスタンス オブジェクト
コンストラクター: コンストラクター
つまり、constructor.prototype がパラメーター オブジェクトのプロトタイプ チェーンに存在するかどうかを検出するために使用されます。
個人的な理解:
instanceof は、左側のオブジェクトが右側のコンストラクターのインスタンス化されたオブジェクトであるかどうか、または左側のオブジェクトがその暗黙のプロトタイプを通じてプロトタイプチェーンを検索できるかどうかを判断するために使用されます**[[proto]]** 関数のプロトタイプオブジェクトに移動しますつまり、関数プロトタイプ オブジェクトがインスタンス オブジェクトのプロトタイプ チェーンにある場合は true を返します。
一般的な理解: 右側が左側の父、祖父、または先祖のいずれであっても、左側のオブジェクトが右側の機能を継承している限り、それは真実です。
インスタンスの使用方法:
object instanceof コンストラクターには、2 つの必須パラメーターがあり、左側はオブジェクト型でなければならず、右側は関数型でなければなりません。戻り値はブール型
注: js のすべてがオブジェクトであると考えるかもしれません.この間違った理解は、すべての人を次のように誤解させるかもしれません: 'str' instanceof String, 戻り値は false です. to String コンストラクター (new String('str')) によって作成された文字列は異なります。コンソールに出力して確認できます。その値は String オブジェクト型の文字列にカプセル化され、同様に new Number(3) instanceof Number、new Boolean(true) instanceof Boolean ... などは true を返します。
コード例:
// 定义构造函数
function C () {}
function D () {}
// 实例化一个 o 对象
var o = new C()
// true,true --> C.prototype 在 o 的原型链上
console.log(o instanceof C, o.__proto__ === C.prototype, '此时 o 的 __proto__:',
o.__proto__, '此时 C 的 prototype:', C.prototype)
// false,false --> D.prototype 不在 o 的原型链上
console.log(o instanceof D, o.__proto__ === D.prototype)
// true true --> Object.prototype 在 o 的原型链上
console.log(o instanceof Object, o.__proto__.__proto__ === Object.prototype)
// 这时我们修改构造函数 C 的原型为一个空对象
C.prototype = {}
// 实例化一个 o2 对象
var o2 = new C()
// true --> C.prototype 在 o2 的原型链上
console.log(o2 instanceof C)
// false,C.prototype 指向了一个空对象,这个空对象不在 o 的原型链上.
console.log(o instanceof C, '此时 o 的 __proto__:', o.__proto__, '此时 C 的 prototype:', C.prototype)
console.log('此时 D 的 prototype:', D.prototype);
// 继承
D.prototype = new C()
console.log('此时 D 的 prototype:', D.prototype);
var o3 = new D()
// true, true --> 因为 o3 是 构造函数 D new 出来的实例对象,所以 D.prototype 一定在 o3 的原型链上
console.log(o3 instanceof D, o3.__proto__ === D.prototype)
// true --> 因为 C.prototype 现在在 o3 的原型链上
console.log(o3 instanceof C)
// true,true --> 上面的结果为什么为 true 呢,看如下代码,D.prototype 是 构造函数 C new 出来的实例对象,所以 C.prototype 一定在 D.prototype 的原型链上
console.log(o3.__proto__ === D.prototype, D.prototype.__proto__ === C.prototype);
// true 相当于如下代码
console.log(o3.__proto__.__proto__ === C.prototype);
手書きを開始
上記から、instanceof 判定の原則は次のとおりであることがわかります。左側のオブジェクトの暗黙のプロトタイプ属性 __ proto __ を介して、プロトタイプ チェーンを層ごとに検索し、右側のコンストラクタのプロトタイプ オブジェクト属性プロトタイプを見つけて、戻ります。真実。これを知っていれば、独自の instanceof を簡単に作成できます。
注: ループを使用して実装する必要があります。
function myInstanceof(obj, func) {
if(!['function', 'object'].includes(typeof obj) || obj === null) {
// 基本数据类型直接返回false,因为不满足instanceof的左侧参数是对象或者说引用类型
return false
}
let objProto = obj.__proto__, funcProto = func.prototype
while(objProto !== funcProto) {
// obj.__proto__不等于func.prototype时,继续通过__proto__向上层查找
// 当找到原型链尽头Object.prototype.__proto__=null 时还未找到,就返回false
objProto = objProto.__proto__
if(objProto === null){
return false
}
}
// obj.__proto__ 等于 prototype = func.prototype 时,不会进入上面循环,返回true
// 不等进入上面循环,找到相等时会跳出循环,走到这里返回true
return true
}
//测试
function A(){}
let a=new A;
console.log(myInstanceof(a,A))//true
console.log(myInstanceof([],A))//false