在 JavaScript 中,`instanceof` 运算符判断构造函数的原型对象是否出现在实例对象的原型链上,请解释其判断原理和内部实现机制?
考察说明
考查对 JavaScript 原型链与 instanceof 运算符底层机制的理解。
回答思路
- 【回答框架 1】`instanceof` 运算符用于检测构造函数的 prototype 属性是否出现在某个对象的原型链上,其核心机制是沿着对象的原型链逐层查找,直到找到与构造函数的 prototype 对象相等的原型或抵达原型链末端。
- 【回答框架 2】内部实现上,以 `obj instanceof Constructor` 为例,会取出 `Constructor.prototype`,然后从 `obj` 的原型开始,通过 `__proto__` 或 `Object.getPrototypeOf` 逐级向上遍历,每次比较当前原型与目标原型是否严格相等。若找到相等则返回 true,若遍历到 null 仍未找到则返回 false。
- 【回答框架 3】需要注意,`instanceof` 的判断基于原型链,而非对象类型本身,因此对于基本类型(如字符串、数字)使用 `instanceof` 时,除非是其包装对象,否则会返回 false。
- 【回答框架 4】如果构造函数的 prototype 属性被修改或重新赋值,会影响后续 `instanceof` 的结果,因为判断时动态读取当前 prototype 值。
- 【回答框架 5】在 ES6 中,`Symbol.hasInstance` 允许自定义构造函数的 `instanceof` 行为,此时会调用该静态方法而非默认的原型链遍历逻辑。
- 【关键点 1】`instanceof` 查找原型链中是否存在构造函数的 prototype 对象。
- 【关键点 2】通过 `__proto__` 链逐级比较,直到 null。
- 【关键点 3】基本类型不适用,除非是包装对象。
- 【关键点 4】修改 prototype 会影响判定结果。
- 【关键点 5】`Symbol.hasInstance` 可自定义判断逻辑。
- 【易错点 1】不要用 `instanceof` 判断基本类型,会得到错误结果。
- 【易错点 2】跨 realm(如 iframe)时,不同全局环境下的构造函数原型不同,判断可能失败。
- 【易错点 3】认为 `instanceof` 能精确判断对象的具体类型,实际它只关心原型链匹配。