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