JS 代码玩具 - instanceof

93 阅读1分钟

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

手写实现

function customInstanceof(left, right) {
  const prototype = right.prototype          // 获取右边构造函数的 prototype 属性
  let proto = Object.getPrototypeOf(left)    // 获取左边对象的原型(基本等同非标方法 left.__proto__)
  while (true) {
    if (proto === null) { return false }     // 如果对象的原型为 null,说明已经到了原型链的末尾
    if (proto === prototype) { return true } // 如果对象的原型等于构造函数的 prototype 属性,说明在原型链上
    proto = Object.getPrototypeOf(proto)     // 继续向上查找原型链
  }
}// 测试示例
function MyClass() {}
const obj = new MyClass()
console.log(customInstanceof(obj, MyClass))  // 输出: true
console.log(customInstanceof(obj, Object))   // 输出: true
console.log(customInstanceof({}, MyClass))   // 输出: false

特殊玩法

自定义 Symbol.hasInstance​ 方法来改变 instanceof​ 运算符的行为,从而让 instanceof​可以用于判断原始类型。

​Symbol.hasInstance​ 是 JavaScript 中的一个内置符号,允许自定义 instanceof​ 运算符的行为。当使用 obj instanceof SomeClass​ 时,JavaScript 引擎实际上会调用 SomeClass[Symbol.hasInstance](obj)​。

class PrimitiveString {
  static Symbol.hasInstance {
    return typeof x === 'string'
  }
}
console.log('hello world' instanceof PrimitiveString)  // true
console.log(123 instanceof PrimitiveString)            // false