instanceof的定义是什么?

instanceof在MDN的定义如下:

标准中

实现instanceof过程

如果实例对象(也就是左边传入的值left__proto__不是强等于构造函数(也就是右边传入的值right)的prototype,就一直朝着实例对象的原型链往上找,直到找到null为止,就证明构造函数的prototype属性并没有出现在实例对象的原型链上。

可以结合下方的示意图来理解一下(图片来自于:mollypages.org)

下面的三种写法均基于这个思想:

while循环写法

function myInstanceOf(left, right) {
  // 取right的显示原型
  let proto = right.prototype;
  // 取left的隐式原型
  left = left.__proto__;
  while (true) {
    if (left === null)
      return false;
    // 当 proto 严格等于 left 时,返回 true
    if (proto === left)
      return true;
    left = left.__proto__;
  }
 }

递归写法

function myInstanceof(left, right) {
  let proto = left.__proto__;
  
  if (!proto) return false;
  
  return right.prototype === proto ? true : myInstanceof(proto, right)
}

for循环写法

function myInstanceof(left, right) {
    let proto = left.__proto__;
    let prototype = right.prototype;
    for (;;) {
        if (proto === null) return false;
        if (proto === prototype) return true;
        proto = proto.__proto__;
    }
}

小优化:Object.getPrototypeOf()

__proto__属性实际上有点过时,在ES6后的编程环境中,更加推荐使用Object.getPrototypeOf()来获取属性。

小提示

本文当中的实现的myInstanceOf只是完成了原型链上查找的部分功能,并未完全模拟,针对类似下面的情况尚未兼容

1 instanceof Number // false
myInstanceof(1, Number) // true
'1' instanceof String // false
myInstanceof('1', String) // true

推荐阅读 & 参考资料

while循环写法参考自,建议深入阅读下方文章

for循环写法参考自

递归写法参考自


修仙大橙子
108 声望17 粉丝

前端工程师