打断施法!教你手撕instanceof源码

368 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情

image.png 这里咱们先来点预备备工作,过程大概是这样的哈:

链表->原型链->instanceof

我们来简单理一理为啥是这么个过程,首先你知道instanceof的基操就是用来检测原型链上是不是存在某个对象原型的值,那么我们就一定涉及到原型链的相关操作,而原型链的本质又是链表。

so,let's take a look! (ᕑᗢᓫ∗)˒

首先你要有一丢丢链表基础

JavaScript中本身没有链表这一数据结构,但我们可以用object来模拟一下

先定义4个object

const a = {val: 1}
const b = {val: 2}
const c = {val: 3}
const d = {val: 4}

然后我们用next属性来把他们关联起来,这里我们设置next属性来模拟指针

于是当我们打印出变量a,一个基础的链表就形成了

a.next = b
b.next = c
c.next = d

console.log(a)
//{ val: 1, next: { val: 2, next: { val: 3, next: [Object] } } }

然后你还得会一点原型链

很多人对原型链抱有深深的恐惧感,但其实,只要明白了原型链的本质也不过是链表,就能轻松地打怪升级啦o( ̄▽ ̄)ブ

  • 原型链的本质是链表
  • 原型链上的节点是各种原型对象,比如Function.prototype、Object.prototype等等
  • 原型链是通过__proto__属性连接各种原型对象

image.png

instanceof

MDN上对instanceof的介绍是

instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上

语法

参数

object->某个实例对象

constructor->某个构造函数

object instanceof constructor

撕它!

OK,现在我们来尝试自己封装一下instanceof函数

思路是这样的,我们用instanceof来判断原型链上是否存在对应的值,那么我们就要沿着原型链往上找,我们会需要一个指针用来移动,如果找得到,就返回true,找不到则返回false。

假设A是实例对象,B要判断是否在A原型链上的值

const instanceOf = (A,B)=>{
    let p = A; // 指针
    p.__proto__ = undefined;
    //先遍历
    while(p){
        // 逻辑
        if(p === B.prototype){
            return true
        }
        p = p.__proto__; // 让p指针指向它的proto
    }
    return false
}

一个基础的instanceof架构就搭建完成了,其实不难对吧,理解它背后的原理和本质,顺着线索一点点去拆解它,所有事物都会变简单哒~(๑•̀ㅂ•́)و✧