此页面由社区从英文翻译而来。了解更多并加入 MDN Web Docs 社区。
Object.prototype.__proto__
已弃用: 不再推荐使用该特性。虽然一些浏览器仍然支持它,但也许已从相关的 web 标准中移除,也许正准备移除或出于兼容性而保留。请尽量不要使用该特性,并更新现有的代码;参见本页面底部的兼容性表格以指导你作出决定。请注意,该特性随时可能无法正常工作。
警告:由于现代 JavaScript 引擎优化属性访问的性质,修改一个对象的[[Prototype]] 在每个浏览器和 JavaScript 引擎中都是非常缓慢的操作。此外,修改继承的效果是微妙和广泛的,不仅限于在obj.__proto__ = ... 语句中花费的时间,而是可能扩展到任何有访问任何已经被修改过[[Prototype]] 的对象的代码。你可以在这里阅读更多信息:JavaScript 引擎基础:优化原型。
备注:使用__proto__ 是有争议且不被鼓励的。它的存在和确切行为仅作为遗留特性被标准化,以确保 Web 兼容性,但它存在一些安全问题和隐患。为了更好的支持,请优先使用Object.getPrototypeOf()/Reflect.getPrototypeOf() 和Object.setPrototypeOf()/Reflect.setPrototypeOf()。
Object 实例的__proto__ 访问器属性暴露了此对象的[[Prototype]](一个对象或null)。
__proto__ 属性还可以在对象字面量定义中使用,作为创建对象时设置对象[[Prototype]] 的一种替代方法,而不是使用Object.create()。请参见:对象初始化/字面量语法。该语法已经标准化,并且在实现中得到了优化,与Object.prototype.__proto__ 相当不同。
In this article
语法
obj.__proto__返回值
如果作为 getter 使用,返回对象的[[Prototype]]。
异常
TypeError如果尝试设置一个不可扩展对象或不可修改原型的特异对象的原型,例如
Object.prototype或window,则会抛出错误。
描述
__proto__ 的 getter 函数暴露了一个对象内部的[[Prototype]] 的值。对于使用对象字面量创建的对象,该值是Object.prototype。对于使用数组字面量创建的对象,该值是Array.prototype。对于函数,该值是Function.prototype。你可以在继承与原型链中了解有关原型链的更多信息。
__proto__ 的 setter 允许修改一个对象的[[Prototype]]。提供的值必须是一个对象或null。提供任何其他值都不会产生任何作用。
与Object.getPrototypeOf() 和Object.setPrototypeOf() 不同,它们始终作为Object 的静态属性存在并始终反映[[Prototype]] 内部属性。__proto__ 属性并不总是作为所有对象的属性存在,因此不能可靠地反映[[Prototype]]。
__proto__ 属性是Object.prototype 上一个简单的访问器属性,由 getter 和 setter 函数组成。如果访问__proto__ 属性时最终查询到Object.prototype,则会找到该属性,但如果没有查询Object.prototype,则不会找到该属性。如果在查询Object.prototype 之前就找到了其他的__proto__ 属性,则会覆盖Object.prototype 上的__proto__ 属性。
null 原型对象不从Object.prototype 继承任何属性,包括__proto__ 访问器属性。因此,如果你尝试在这样的对象上读取__proto__,则无论对象的实际[[Prototype]] 是什么,该值都将始终为undefined,并且对__proto__ 的任何赋值都将创建一个名为__proto__ 的新属性,而不是设置对象的原型。此外,__proto__ 可以通过Object.defineProperty() 作为任何对象实例的自有属性重新定义,而不触发 setter。在这种情况下,__proto__ 将不再是[[Prototype]] 的访问器。因此,为设置和获取对象的[[Prototype]],请始终使用Object.getPrototypeOf() 和Object.setPrototypeOf()。
示例
>使用 __proto__
function Circle() {}const shape = {};const circle = new Circle();// 设置该对象的原型// 已弃用。这里只是举个例子,请不要在生产环境中这样做。shape.__proto__ = circle;// 判断该对象的原型链引用是否属于 circleconsole.log(shape.__proto__ === circle); // trueconst ShapeA = function () {};const ShapeB = { a() { console.log("aaa"); },};ShapeA.prototype.__proto__ = ShapeB;console.log(ShapeA.prototype.__proto__); // { a: [Function: a] }const shapeA = new ShapeA();shapeA.a(); // aaaconsole.log(ShapeA.prototype === shapeA.__proto__); // trueconst ShapeC = function () {};const ShapeD = { a() { console.log("a"); },};const shapeC = new ShapeC();shapeC.__proto__ = ShapeD;shapeC.a(); // aconsole.log(ShapeC.prototype === shapeC.__proto__); // falsefunction Test() {}Test.prototype.myName = function () { console.log("myName");};const test = new Test();console.log(test.__proto__ === Test.prototype); // truetest.myName(); // myNameconst obj = {};obj.__proto__ = Test.prototype;obj.myName(); // myName规范
| Specification |
|---|
| ECMAScript® 2026 Language Specification> # sec-object.prototype.__proto__> |