极客时间返利平台,你可以在上边通过山月的链接购买课程,并添加我的微信 (shanyue94) 领取返现。
山月训练营之面试直通车 服务上线了,从准备简历、八股文准备、项目经历准备、面试、面经、面经解答、主观问题答复、谈薪再到入职的一条龙服务。

# JS 中如何原生实现 instanceOf

更多描述

function fakeInstanceOf(instance, parent): Boolean {}

//=> true
fakeInstanceOf([], Array);

//=> true
fakeInstanceOf([], Object);

//=> true
fakeInstanceOf((x) => x, Object);

//=> false
fakeInstanceOf("hello", Object);

Issue

欢迎在 Gtihub Issue 中回答此问题: Issue 710 (opens new window)

function fakeInstanceOf(instance, parent) {
  if (typeof instance !== "object" && typeof instance !== "function") {
    return false;
  }
  let proto = instance?.__proto__ || null;
  while (true) {
    if (proto === null) {
      return false;
    }
    if (proto === parent.prototype) {
      return true;
    }
    proto = proto.__proto__;
  }
}

Author

回答者: ywang305 (opens new window)

function fakeInstanceOf (instance, parent) {
  if(! instance?.__proto__ ||  ! parent.prototype) return false;
  if( instance.__proto__ === parent.prototype ) return true;
  return fakeInstanceOf(instance, parent.prototype
}
function typeObj(val) {
  if ((typeof val === "function" || typeof val === "object") && val !== null) {
    return true;
  } else {
    return false;
  }
}

function instanceOf(left, right) {
  if (!typeObj(right)) {
    throw new Error("error info");
  }
  let hasInstance = right[Symbol.hasInstance];
  if (hasInstance !== undefined && typeof hasInstance === "function") {
    return !!hasInstance.call(right, left);
  } else {
    if (typeof right !== "function") {
      throw new Error("error info");
    }
    if (!typeObj(left)) return false;
    let proto = right.prototype;
    if (!typeObj(proto)) throw new Error("error Info");
    let leftProto = left.prototype;
    while (leftProto !== null) {
      if (leftProto === proto) return true;
      leftProto = leftProto.prototype;
    }
    return false;
  }
}
// left instanceof right
function _instanceof(left, right) {
  // 构造函数原型
  const prototype = right.prototype;
  // 实列对象属性,指向其构造函数原型
  left = left.__proto__;
  // 查实原型链
  while (true) {
    // 如果为null,说明原型链已经查找到最顶层了,真接返回false
    if (left === null) {
      return false;
    }
    // 查找到原型
    if (prototype === left) {
      return true;
    }
    // 继续向上查找
    left = left.__proto__;
  }
}

const str = "abc";
_instanceof(str, String); // true
function fakeInstanceOf(left, right) {
  if (!left) return false;
  if (typeof left !== "object" && typeof left !== "function") return false;
  let proto = left.__proto__;
  const prototype = right.prototype;

  while (proto) {
    if (proto === prototype) {
      return true;
    }
    proto = proto.__proto__;
  }

  return false;
}

Author

回答者: penghei (opens new window)

有一个小问题问一下大家 代码中判断当前对象是否等于函数 prototype 的方法是直接用相等判断,即类似这样:

if(parentProto===childProto)

但是有个问题就是,不管是函数的 prototype 还是对象的__proto__,实际上都是对象,对象之间为什么能用===判断相等?

@penghei 因为他们是同一个对象啊

Author

回答者: vikoala (opens new window)

@penghei 因为他们指向同一个对象

Last Updated: 11/4/2022, 6:34:31 PM