在这里插入图片描述

最简单实现

function instanceof(left, right) {
    let leftValue = left.__proto__;
    while (true) {
        if (leftValue === null) return false;
        if (leftValue === right.prototype) return true;
        leftValue = leftValue.__proto__;
    }
}

全面实现

function instanceOf(left, right) {
 if (typeof right !== "function")
   throw new TypeError(
     "Uncaught TypeError: Right-hand side of " instanceof
       " is not an object"
   );
 if (obj === null || !/^(object|function)$/i.test(typeof left))
   return false;
 if (!right.prototype)
   throw new TypeError(
     "TypeError: Function has non-object prototype 'undefined' in instanceof check"
   );

 let hasInstance =
   typeof Symbol !== "undefined" && right[Symbol.hasInstance];
 if (hasInstance) {
   return hasInstance.call(right, left);
   /* right[Symbol.hasInstance](left) */
 }
 let proto = Object.getPrototypeOf(obj);
 while (proto) {
   if (proto === right.prototype) return true;
   proto = Object.getPrototypeOf(proto);
 }
 return false;
}

为啥用instanceof

  1. typeof null -> ‘object’
  2. typeof 不能细分对象 除了函数外
  3. 所有数据类型值 在计算机底层都是64位 2进制来存储的 所有的对象数据类型值,前三位
  4. 都是0,而null存储的二进制全是0
  5. typeof 就是按照二进制值来进行检测的 性能好,例如 他认为前三位是0 都是对象,在这基础
  6. 上再看对象有没有实现call 实现call了 结果是funciton 没有实现 结果就是‘object’,
  7. 所以 typeof null结果就是 ‘object’ 也不能细分对象
  8. typeof 检测一个未被声明的变量 不会报错 结果是 undefined 排除这个变量在后面会被let/const声明
  9. left instanceof right 先检测 right是否有Symbol.hasInstance 这个属性方法,如果存在,则基于
  10. 这个方法进行检测 rightSymbol.hasInstance
  11. 如果没有这个属性方法,获取value的原型链,直到找到Object.prototype,如果right.prototype出现在
  12. 他的原型链上,则证明value是right的实例,反之则不是
  13. 在新版本浏览器中 在Function.prototype上存在一个属性方法 Symbol.hasInstance,所以只要是函数
  14. 无论是普通函数还是构造函数 都具备Symbol.hasInstance这个方法
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐