The instanceof method of JS is handwritten

method introduction

What is instanceof?

Used to detect whether the prototype attribute of the constructor appears on the prototype chain of an instance object .

Syntax: object instanceof constructor
object: an instance object
constructor: a constructor

In short, it is used to detect whether constructor.prototype exists on the prototype chain of the parameter object.

Personal understanding:

instanceof is used to judge whether the left object is an instantiated object of the right constructor , or whether the left object can search up the prototype chain through its implicit prototype **[[proto]]** Go to the prototype object of the function on the right, that is, return true if the function prototype object appears on the prototype chain of the instance object.

Popular understanding: Whether the right side is the father, grandfather, or ancestor of the left side, as long as the left side object inherits from the right side function, it is true

How to use instanceof:

object instanceof constructor, it has two required parameters, the left side must be an object type, and the right side must be a function type. The return value is Boolean type

Note: You may think that everything in js is an object. This wrong understanding may mislead everyone to appear in this way: 'str' instanceof String, the return value is false, because 'str' is a simple string, and it is related to String The string created by the constructor (new String('str')) is different, you can print it out on the console to see, its value will be encapsulated into a string of String object type, similarly new Number(3) instanceof Number, new Boolean(true) instanceof Boolean ... and so on return true.

Code example:

// 定义构造函数
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);

start handwriting

From the above, we can know that the principle of instanceof judgment is: through the implicit prototype attribute __ proto __ of the left object, search up the prototype chain layer by layer, find the prototype object attribute prototype of the right constructor, and return true. Knowing this makes it easy to write your own instanceof.

Note: It needs to be implemented with the aid of a loop.

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

Guess you like

Origin blog.csdn.net/m0_65335111/article/details/127602834