使用Object.setPrototypeOf后,如何获取对象的原始构造函数名?
问题解答
Chrome DevTools能识别出实例原本属于Example构造函数,核心原因是Chrome基于的V8引擎会为每个对象维护内部隐藏的元数据,比如存储对象创建时关联的原始构造函数。这部分信息不会因为你修改__proto__而被清除,但普通JavaScript代码无法直接访问这些内部属性(比如V8的[[Constructor]]内部槽位)。
如果是实验场景,想在JS代码里实现类似DevTools的识别效果,可以试试这两种方案:
- 给实例添加不可枚举的标记属性:在修改原型之前,给实例绑定一个不会被遍历到的属性,存储原始构造函数信息:
const example = new function Example() { // 提前标记原始构造函数,设为不可枚举避免干扰 Object.defineProperty(this, '__originalCtor', { value: Example, enumerable: false, configurable: false }); const self = Object.setPrototypeOf(this, { get name(){ return self.__originalCtor.name; }, }); }; console.log(example.name); // 输出 "Example"
- 用WeakMap存储实例与构造函数的映射:不想污染实例本身的话,可以用WeakMap来关联实例和对应的原始构造函数,WeakMap的键是弱引用,不会影响实例的垃圾回收:
const instanceToCtor = new WeakMap(); const example = new function Example() { instanceToCtor.set(this, Example); const self = Object.setPrototypeOf(this, { get name(){ return instanceToCtor.get(self).name; }, }); }; console.log(example.name); // 输出 "Example"
要明确的是,这些都是手动记录的方案,并非直接读取引擎的内部元数据——普通JS没有权限访问V8的内部槽位。而DevTools作为浏览器的调试工具,拥有特殊权限可以读取这些隐藏信息,所以能直接识别出对象的原始构造函数。
内容的提问来源于stack exchange,提问作者Alexander Nenashev
相关产品推荐
相关产品推荐

