You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

fn.constructor与Object.getPrototypeOf(fn).constructor是否会不一致?

JS 中obj.constructor与Object.getPrototypeOf(obj).constructor的不一致场景

二者核心的访问逻辑本身就存在差异:

  • obj.constructor会沿着实例的完整原型链向上查找,返回第一个匹配到的constructor属性值
  • Object.getPrototypeOf(obj).constructor直接读取实例的直接原型上的constructor属性,不会从实例自身开始查找

以下是非常容易出现二者不一致的场景:

场景1:实例自身挂载了自定义constructor属性

这是最常见的不一致场景,对象自有属性的优先级高于原型链属性,直接会覆盖取值:

class Foo {}
const myFoo = new Foo();
// 给实例自身添加constructor属性,覆盖原型链上的默认取值
myFoo.constructor = function Bar() {};

const constructor1 = myFoo.constructor; // 输出 Bar
const constructor2 = Object.getPrototypeOf(myFoo).constructor; // 输出 Foo
// 二者完全不相等

场景2:实例被 Proxy 代理,拦截了constructor属性访问

如果用 Proxy 对实例做了封装,自定义拦截了constructor属性的读取逻辑,就会出现不一致:

class Foo {}
const myFoo = new Foo();
const proxyIns = new Proxy(myFoo, {
  get(target, prop) {
    if (prop === 'constructor') return Number;
    return Reflect.get(target, prop);
  }
});

const constructor1 = proxyIns.constructor; // 输出 Number
const constructor2 = Object.getPrototypeOf(proxyIns).constructor; // 输出 Foo

序列化场景的开发建议

如果你需要可靠获取实例对应的构造函数用于反序列化,可以参考以下实践:

  • 用Object.hasOwn(obj, 'constructor')先判断实例是否有自定义的自有constructor属性,再根据业务逻辑决定是否采信该值
  • 优先使用Object.getPrototypeOf(obj)?.constructor取值,可以规避实例自定义constructor属性的干扰
  • 针对Object.create(null)创建的无原型实例,要做好空值兜底,避免访问属性时报错

内容的提问来源于stack exchange,提问作者Julian Lachniet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 02:18:03