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__完全不同。

语法

js
obj.__proto__

返回值

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

异常

TypeError

如果尝试设置不可扩展对象或不可变原型外来对象(例如Object.prototypewindow)的原型,则会抛出此异常。

描述

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

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

规范

规范
ECMAScript 语言规范
# sec-object.prototype.__proto__

浏览器兼容性

BCD 表仅在启用 JavaScript 的浏览器中加载。

另请参阅