Object.prototype.proto
Deprecated: This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the compatibility table at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.
警告:根据现代 JavaScript 引擎优化属性访问的本质,更改对象的
[[Prototype]]
目前在每个浏览器和 JavaScript 引擎中都是非常缓慢的操作。此外,更改继承的影响是微妙且广泛的,并且不限于花费在obj.__proto__ = ...
语句中的时间,而是可能扩展到有权访问[[Prototype]]
已更改的任何对象的任何代码。你可以在 JavaScript 引擎基础知识:优化原型 中阅读更多内容。¥Warning: Changing the
[[Prototype]]
of an object is, by the nature of how modern JavaScript engines optimize property accesses, currently a very slow operation in every browser and JavaScript engine. In addition, the effects of altering inheritance are subtle and far-flung, and are not limited to the time spent in theobj.__proto__ = ...
statement, but may extend to any code that has access to any object whose[[Prototype]]
has been altered. You can read more in JavaScript engine fundamentals: optimizing prototypes.
注意:
__proto__
的使用存在争议且不鼓励。它的存在和确切行为仅被标准化为遗留功能,以确保网络兼容性,同时它也带来了一些安全问题和威胁。为了获得更好的支持,请优先选择Object.getPrototypeOf()
/Reflect.getPrototypeOf()
和Object.setPrototypeOf()
/Reflect.setPrototypeOf()
。¥Note: The use of
__proto__
is controversial and discouraged. Its existence and exact behavior have only been standardized as a legacy feature to ensure web compatibility, while it presents several security issues and footguns. For better support, preferObject.getPrototypeOf()
/Reflect.getPrototypeOf()
andObject.setPrototypeOf()
/Reflect.setPrototypeOf()
instead.
Object
实例的 __proto__
访问器属性公开该对象的 [[Prototype]]
(对象或 null
)。
¥The __proto__
accessor property of Object
instances exposes the [[Prototype]]
(either an object or null
) of this object.
__proto__
属性还可以在对象字面定义中使用,以在创建时设置对象 [[Prototype]]
,作为 Object.create()
的替代。看:对象初始值设定项/文字语法。该语法是标准的,并针对实现进行了优化,与 Object.prototype.__proto__
有很大不同。
¥The __proto__
property can also be used in an object literal definition to set the object [[Prototype]]
on creation, as an alternative to Object.create()
. See: object initializer / literal syntax. That syntax is standard and optimized for in implementations, and quite different from Object.prototype.__proto__
.
语法
返回值
例外情况
描述
¥Description
__proto__
getter 函数公开对象内部 [[Prototype]]
的值。对于使用对象字面量创建的对象(除非你使用 原型设定者 语法),该值为 Object.prototype
。对于使用数组文字创建的对象,该值为 Array.prototype
。对于函数,该值为 Function.prototype
。你可以在 继承和原型链 中阅读有关原型链的更多信息。
¥The __proto__
getter function exposes the value of the internal [[Prototype]]
of an object. For objects created using an object literal (unless you use the prototype setter syntax), this value is Object.prototype
. For objects created using array literals, this value is Array.prototype
. For functions, this value is Function.prototype
. You can read more about the prototype chain in Inheritance and the prototype chain.
__proto__
setter 允许改变对象的 [[Prototype]]
。提供的值必须是对象或 null
。提供任何其他值将无济于事。
¥The __proto__
setter allows the [[Prototype]]
of an object to be mutated. The value provided must be an object or null
. Providing any other value will do nothing.
与 Object.getPrototypeOf()
和 Object.setPrototypeOf()
不同,Object.getPrototypeOf()
和 Object.setPrototypeOf()
始终作为静态属性在 Object
上可用,并且始终反映 [[Prototype]]
内部属性,而 __proto__
属性并不总是作为所有对象上的属性存在,因此不能可靠地反映 [[Prototype]]
。
¥Unlike Object.getPrototypeOf()
and Object.setPrototypeOf()
, which are always available on Object
as static properties and always reflect the [[Prototype]]
internal property, the __proto__
property doesn't always exist as a property on all objects, and as a result doesn't reflect [[Prototype]]
reliably.
__proto__
属性是 Object.prototype
上的简单访问器属性,由 getter 和 setter 函数组成。最终查阅 Object.prototype
的 __proto__
属性访问将找到该属性,但不查阅 Object.prototype
的访问则不会找到。如果在查询 Object.prototype
之前找到其他 __proto__
属性,则该属性将隐藏在 Object.prototype
上找到的属性。
¥The __proto__
property is a simple accessor property on Object.prototype
consisting of a getter and setter function. A property access for __proto__
that eventually consults Object.prototype
will find this property, but an access that does not consult Object.prototype
will not. If some other __proto__
property is found before Object.prototype
is consulted, that property will hide the one found on Object.prototype
.
null
-原型对象 不会从 Object.prototype
继承任何属性,包括 __proto__
访问器属性,因此,如果你尝试读取此类对象上的 __proto__
,则该值始终为 undefined
,而不管该对象的实际 [[Prototype]]
,并且对 __proto__
的任何赋值都会创建一个新属性 调用 __proto__
而不是设置对象的原型。此外,可以通过 Object.defineProperty()
将 __proto__
重新定义为任何对象实例上自己的属性,而无需触发 setter。在这种情况下,__proto__
将不再是 [[Prototype]]
的访问器。因此,总是首选 Object.getPrototypeOf()
和 Object.setPrototypeOf()
来设置和获取对象的 [[Prototype]]
。
¥null
-prototype objects don't inherit any property from Object.prototype
, including the __proto__
accessor property, so if you try to read __proto__
on such an object, the value is always undefined
regardless of the object's actual [[Prototype]]
, and any assignment to __proto__
would create a new property called __proto__
instead of setting the object's prototype. Furthermore, __proto__
can be redefined as an own property on any object instance through Object.defineProperty()
without triggering the setter. In this case, __proto__
will no longer be an accessor for [[Prototype]]
. Therefore, always prefer Object.getPrototypeOf()
and Object.setPrototypeOf()
for setting and getting the [[Prototype]]
of an object.
示例
使用 proto
¥Using __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
规范
Specification |
---|
ECMAScript Language Specification # sec-object.prototype.__proto__ |
浏览器兼容性
BCD tables only load in the browser