__proto__ 是es6附录b中的非标准遗留特性,仅限浏览器兼容,新代码不应使用;应改用object.getprototypeof()、object.setprototypeof()和object.create()等标准api。

__proto__ 在 ES6 中并未被纳入规范正文,而是以“附录 B”的形式存在,明确标注为**仅针对浏览器环境的遗留兼容性特性**。它本质上是内部属性(双下划线命名暗示非公开 API),不是标准的、推荐使用的语言功能。
规范定位:附录 B,非强制标准
ES6(ECMAScript 2015)标准将 __proto__ 放在附录 B.3.1 节,标题为 “Additional Properties of the Object.prototype Object”。文档特别强调:
- 该属性仅要求浏览器必须实现,其他运行环境(如 Node.js 早期版本、某些嵌入式 JS 引擎)可选择不支持;
- 它不是正式对外 API,语义上属于历史包袱,而非设计演进;
- 标准明确建议:“new code should not use this property”(新代码不应使用此属性)。
替代方案:ES6 标准化方法
ES6 提供了语义清晰、行为确定、跨环境兼容的标准 API,完全覆盖 __proto__ 的读写需求:
-
读取原型:用
Object.getPrototypeOf(obj)—— 稳定、无副作用; -
设置原型:用
Object.setPrototypeOf(obj, prototype)—— 明确意图,便于引擎优化; -
创建指定原型的对象:用
Object.create(prototype, descriptors)—— 更安全、更高效。
兼容性现实:能用 ≠ 应该用
虽然现代浏览器(含 IE11)普遍支持 __proto__,但存在明显风险:
- 性能损耗:直接修改 __proto__ 可能触发对象隐藏类失效,导致 V8 等引擎降级优化;
- 静态分析困难:构建工具(如 Webpack、ESLint)和类型系统(如 TypeScript)难以准确推导其影响;
- 服务端不可靠:Node.js 在 v4–v12 中曾默认禁用或需 flag 启用,部分 Deno/QuickJS 环境完全不支持。
特殊情况下的有限容忍
极少数场景可能见到它,但需谨慎评估:
- 维护遗留代码(如 jQuery 1.x、旧版框架 polyfill);
- 调试时临时查看原型链(
console.log(obj.__proto__)); - 某些底层库为兼容极老环境做的兜底逻辑(通常包裹在
typeof obj.__proto__ !== 'undefined'检测中)。











