Object.prototype.__proto__
已弃用:此功能不再推荐。尽管某些浏览器可能仍然支持它,但它可能已从相关的 Web 标准中删除,可能正在被删除,或者可能仅出于兼容性目的而保留。避免使用它,并尽可能更新现有代码;请参阅此页面底部的兼容性表以指导您的决策。请注意,此功能可能随时停止工作。
警告:更改对象的[[Prototype]]
本质上是现代 JavaScript 引擎如何优化属性访问的方式,目前在每个浏览器和 JavaScript 引擎中都是非常慢的操作。此外,更改继承的影响是微妙且广泛的,不仅限于obj.__proto__ = ...
语句中花费的时间,还可能扩展到任何可以访问其[[Prototype]]
已更改的任何对象的代码。您可以在JavaScript 引擎基础知识:优化原型中了解更多信息。
注意:__proto__
的使用存在争议,不建议使用。它的存在和确切行为仅作为一项遗留功能被标准化,以确保 Web 兼容性,同时它也存在一些安全问题和陷阱。为了获得更好的支持,建议使用Object.getPrototypeOf()
/Reflect.getPrototypeOf()
和Object.setPrototypeOf()
/Reflect.setPrototypeOf()
代替。
__proto__
是Object
实例的访问器属性,它公开了此对象的[[Prototype]]
(一个对象或null
)。
__proto__
属性也可用于对象字面量定义中,以在创建时设置对象的[[Prototype]]
,作为Object.create()
的替代方案。请参阅:对象初始化程序/字面量语法。该语法是标准化的,并在实现中进行了优化,并且与Object.prototype.__proto__
完全不同。
语法
obj.__proto__
返回值
如果用作 getter,则返回对象的[[Prototype]]
。
异常
描述
__proto__
getter 函数公开了对象的内部[[Prototype]]
的值。对于使用对象字面量创建的对象(除非您使用原型 setter语法),此值为Object.prototype
。对于使用数组字面量创建的对象,此值为Array.prototype
。对于函数,此值为Function.prototype
。您可以在继承和原型链中详细了解原型链。
__proto__
setter 允许更改对象的[[Prototype]]
。提供的值必须是对象或null
。提供任何其他值都不会有任何作用。
与Object.getPrototypeOf()
和Object.setPrototypeOf()
不同,后者始终作为静态属性在Object
上可用,并始终反映[[Prototype]]
内部属性,__proto__
属性并不总是作为所有对象的属性存在,因此并不能可靠地反映[[Prototype]]
。
__proto__
属性是Object.prototype
上的一个简单的访问器属性,由 getter 和 setter 函数组成。最终查询Object.prototype
的__proto__
属性访问将找到此属性,但不会查询Object.prototype
的访问则不会找到。如果在查询Object.prototype
之前找到其他__proto__
属性,则该属性将隐藏在Object.prototype
上找到的属性。
null
原型对象不会从Object.prototype
继承任何属性,包括__proto__
访问器属性,因此如果您尝试读取此类对象的__proto__
,则无论对象的实际[[Prototype]]
是什么,其值始终为undefined
,并且对__proto__
的任何赋值都将创建一个名为__proto__
的新属性,而不是设置对象的原型。此外,可以通过Object.defineProperty()
在任何对象实例上将__proto__
重新定义为自身属性,而不会触发 setter。在这种情况下,__proto__
将不再是[[Prototype]]
的访问器。因此,始终建议使用Object.getPrototypeOf()
和Object.setPrototypeOf()
来设置和获取对象的[[Prototype]]
。
示例
使用 __proto__
function Circle() {}
const shape = {};
const circle = new Circle();
// Set the object prototype.
// DEPRECATED. This is for example purposes only. DO NOT DO THIS in real code.
shape.__proto__ = circle;
// Get the object prototype
console.log(shape.__proto__ === Circle); // false
const 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(); // aaa
console.log(ShapeA.prototype === shapeA.__proto__); // true
const ShapeC = function () {};
const ShapeD = {
a() {
console.log("a");
},
};
const shapeC = new ShapeC();
shapeC.__proto__ = ShapeD;
shapeC.a(); // a
console.log(ShapeC.prototype === shapeC.__proto__); // false
function Test() {}
Test.prototype.myName = function () {
console.log("myName");
};
const test = new Test();
console.log(test.__proto__ === Test.prototype); // true
test.myName(); // myName
const obj = {};
obj.__proto__ = Test.prototype;
obj.myName(); // myName
规范
规范 |
---|
ECMAScript 语言规范 # sec-object.prototype.__proto__ |
浏览器兼容性
BCD 表仅在启用 JavaScript 的浏览器中加载。