结论:应优先使用Object.getPrototypeOf()而非__proto__;前者是标准、稳定、语义清晰的API,后者非标准、有性能隐患且行为不一致,仅在极老环境polyfill中才考虑使用。

直接说结论:__proto__ 是对象身上的可读写属性,Object.getPrototypeOf() 是标准函数调用;前者语法简洁但非标准、有副作用风险,后者语法稍长但语义清晰、行为稳定、性能更可控。
语法差异:写法、参数与适用范围不同
__proto__ 是每个普通对象(除 null)自带的属性,访问方式是点操作符或方括号:
-
obj.__proto__—— 直接读取,最简写法 -
obj["__proto__"]—— 动态访问,等价但不常用 - 它只存在于对象实例上,函数也有 __proto__,但它的 prototype 属性不是 __proto__
- 不能对原始值(如
"abc"、42)使用,会返回undefined(非报错)
Object.getPrototypeOf() 是静态方法,必须传参调用:
-
Object.getPrototypeOf(obj)—— 参数必须是对象,否则抛TypeError - 对原始值(如字符串、数字)会自动包装成对象再取原型,例如
Object.getPrototypeOf("x") === String.prototype - 对
Object.create(null)返回null,符合预期;而obj.__proto__在这种对象上也是undefined(注意:不是null)
性能表现:__proto__ 看似快,实则隐患多
表面上看,obj.__proto__ 是属性访问,比函数调用少一层开销。但实际开发中,它带来的性能问题远大于这点微小优势:
- 浏览器引擎对
__proto__的访问常做特殊处理,尤其在修改时(如赋值),可能触发隐藏类失效,导致 JIT 编译器降级优化 - 频繁读取
__proto__且后续用于条件分支时,容易让 V8 等引擎放弃内联缓存(IC),降低整体执行效率 -
Object.getPrototypeOf()是标准化接口,引擎对其做了充分优化,现代 JS 引擎(如 V8、SpiderMonkey)已将其视为“稳定内建”,调用开销极低 - 更重要的是:性能差异在绝大多数场景下不可测量;而可维护性、兼容性和调试成本的差距却非常真实
什么时候该用哪一个?明确推荐边界
除非你在写兼容极老环境(IE10 及以下)的 polyfill,否则一律优先用 Object.getPrototypeOf():
- 需要判断类型或遍历原型链时(如
Object.getPrototypeOf(arr) === Array.prototype),这是唯一可靠方式 - 跨 iframe 场景下,
instanceof失效,但Object.getPrototypeOf()仍能准确识别原生构造器原型 - 调试时查看原型结构,控制台中
console.log(Object.getPrototypeOf(obj))比依赖__proto__更稳定 - 绝对不要给
__proto__赋值——改用Object.setPrototypeOf()(仅限必要场景,因它本身也有性能代价)
一个容易踩坑的对比示例
下面两段代码看似等价,但行为和含义完全不同:
const arr = []; console.log(arr.__proto__ === Array.prototype); // true(但 __proto__ 非标准) console.log(Object.getPrototypeOf(arr) === Array.prototype); // true(标准、可靠)
再看这个:
const obj = Object.create(null); console.log(obj.__proto__); // undefined(不是 null!易误判) console.log(Object.getPrototypeOf(obj)); // null(明确无原型)
这种差异在类型检测逻辑里可能引发隐蔽 bug。


















