手写系列 - instanceof运算符

91 阅读1分钟

instanceof 的定义

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

语法

object instanceof constructor

object 某个实例对象

constructor 某个构造函数

function _instanceof(object, constructor) {
  // 如果左边传入的不是对象,返回false
  if (typeof object !== "object") return false;
  // 如果右边没有 prototype 属性,抛出错误
  if (!constructor.prototype) {
    throw new Error("Right-hand side of 'instanceof' is not callable");
  }
  let link = object;
  while (link !== null) {
    // __proto__ 属性已被弃用,可能在判断时会存在一些问题,使用 Object.getPrototypeOf() 代替
    if (Object.getPrototypeOf(link) === constructor.prototype) return true;
    link = Object.getPrototypeOf(link);
  }
  return false; // 查到顶层的 null 对象,实例对象的原型链上没有构造函数的 prototype 属性
}

测试一下:

const simpleStr = "This is a simple string";
const myString = new String();
const newStr = new String("String created with constructor");
const myDate = new Date();
const myObj = {};
const myNonObj = Object.create(null);

simpleStr instanceof String; // 返回 false,非对象实例,因此返回 false
console.log(_instanceof(simpleStr, String));

myString instanceof String; // 返回 true
console.log(_instanceof(myString, String));

newStr instanceof String; // 返回 true
console.log(_instanceof(newStr, String));

myString instanceof Object; // 返回 true
console.log(_instanceof(myString, Object));

myObj instanceof Object; // 返回 true,尽管原型没有定义
console.log(_instanceof(myObj, Object));

({}) instanceof Object; // 返回 true,同上
console.log(_instanceof({}, Object));

myNonObj instanceof Object; // 返回 false,一种创建非 Object 实例的对象的方法
console.log(_instanceof(myNonObj, Object));

myString instanceof Date; //返回 false
console.log(_instanceof(myString, Date));

myDate instanceof Date; // 返回 true
console.log(_instanceof(myDate, Date));

myDate instanceof Object; // 返回 true
console.log(_instanceof(myDate, Object));

myDate instanceof String; // 返回 false
console.log(_instanceof(myDate, String));