object.getprototypeof()是获取对象原型的标准安全方法,用于类型判断、原型链遍历、结构校验、真实溯源,并应替代__proto__实现读写与创建操作。

Object.getPrototypeOf() 是获取对象原型的标准方法,它读取的是对象内部 [[Prototype]] 槽的真实值,行为稳定、语义明确,且在严格模式和跨环境场景中完全可靠。它不修改对象,只读取,因此比非标准的 __proto__ 更安全、更推荐。
常见使用场景
类型判断与跨上下文识别
在 iframe 或微前端等多 JS 执行环境场景中,instanceof 会失效(因构造函数不共享),但原型对象本身可被直接比较:
– Object.getPrototypeOf(arr) === Array.prototype 比 arr instanceof Array 更底层、更可靠;
– 同样可用于识别 Date、RegExp、自定义类实例,不受构造函数名混淆或重写影响。
原型链遍历与调试
用于手动向上追踪继承结构,比如排查方法来源或验证继承是否生效:
– 循环调用: let p = obj; while (p = Object.getPrototypeOf(p)) { console.log(p); };
– 终止条件是 null,避免无限循环;
– 在类继承或框架调试中,快速确认子类实例的原型是否正确指向父类 prototype。
对象合并前的结构校验
合并操作(如插件注入、配置叠加)常需区分“普通数据对象”和“带行为的对象”:
– 若 Object.getPrototypeOf(source) === Object.prototype,说明它是裸对象,可用 Object.assign 安全合并;
– 若返回 Array.prototype 或某个类的 prototype,则表明其方法依赖原型链,直接 assign 会丢失行为,应改用 Object.create + 属性复制;
– 对 Object.create(null) 创建的对象,getPrototypeOf 返回 null,提示需手动补全基础能力(如挂载 hasOwnProperty)。
绕过 constructor 污染做真实溯源
混淆代码常篡改 constructor 或重写 toString,但无法伪造内部 [[Prototype]]:
– 即使 obj.constructor = null,Object.getPrototypeOf(obj) 仍能返回真实的原型;
– 结合 Object.prototype.toString.call(obj) 和原型上的方法签名(如 push、test),可交叉验证原始类型与构造意图。
如何替代 __proto__
读取原型时,一律用 Object.getPrototypeOf()
– 替代 obj.__proto__:直接写 Object.getPrototypeOf(obj);
– 它对非对象输入(null、undefined)抛 TypeError,便于早期发现问题;
– 对原始值(如字符串 "abc")会自动包装,返回 String.prototype,行为定义清晰。
设置原型时,用 Object.setPrototypeOf()
– 替代 obj.__proto__ = newProto:改用 Object.setPrototypeOf(obj, newProto);
– 注意:该操作有性能代价,应谨慎使用;优先考虑创建新对象:Object.create(newProto, descriptors);
– 不要混用:读用 getPrototypeOf,写用 setPrototypeOf,形成规范配对。
创建对象时,用 Object.create() 代替 { __proto__: ... }
– 虽然 { __proto__: proto } 已被 ES6 接纳为语法糖,但它只是特定上下文的简写;
– 生产代码中应优先使用 Object.create(proto, propertyDescriptors),支持完整属性描述符控制,更安全、更灵活。
避免任何对 __proto__ 的显式引用
– 不在条件判断中写 if (obj.__proto__ === Array.prototype);
– 不在日志或调试中依赖 obj.__proto__ 输出;
– 不将其作为公共 API 暴露给外部调用;
– 模板字符串、动态属性访问等场景也应规避。











