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 the obj.__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, prefer Object.getPrototypeOf()/Reflect.getPrototypeOf() and Object.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__.

语法

¥Syntax

js
obj.__proto__

返回值

¥Return value

如果用作 getter,则返回对象的 [[Prototype]]

¥If used as a getter, returns the object's [[Prototype]].

例外情况

¥Exceptions

TypeError

如果尝试设置 non-extensible 对象或 不可变原型外来对象(例如 Object.prototypewindow)的原型,则抛出该异常。

描述

¥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.

示例

¥Examples

使用 proto

¥Using __proto__

js
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
js
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
js
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
js
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__

¥Specifications

浏览器兼容性

BCD tables only load in the browser

¥Browser compatibility

也可以看看