--- title: Object.prototype.__proto__ slug: Web/JavaScript/Reference/Global_Objects/Object/proto translation_of: Web/JavaScript/Reference/Global_Objects/Object/proto ---
Warning: 基於現代Javascript引擎最佳化物件屬性存取的方法,改變一個物件的 [[Prototype]]
在任何瀏覽器或是Javascript引擎都是非常慢的操作?。改變繼承屬性對效能的影響微妙且深遠,不僅僅只是影響執行 obj.__proto__ = ...
的時間,而是會影響到所有有存取到被改變 [[Prototype]]
的物件的程式碼的執行時間。如果你在乎效能的話就應該避免改變一個物件的 [[Prototype]]
。反之,請用 {{jsxref("Object.create()")}} 來產生一個擁有 [[Prototype]]
的物件。
Warning: 雖然 Object.prototype.__proto__
在今日已經被絕大部分的瀏覽器所支援,其存在與確切的行為只有在 ECMAScript 2015 規範才被標準化成一個歷史功能來確保相容性。為了更好的支援,建議使用{{jsxref("Object.getPrototypeOf()")}}。
The __proto__
property of {{jsxref("Object.prototype")}} is an accessor property (a getter function and a setter function) that exposes the internal [[Prototype]]
(either an object or {{jsxref("Global_Objects/null", "null")}}) of the object through which it is accessed.
The use of __proto__
is controversial, and has been discouraged. It was never originally included in the EcmaScript language spec, but modern browsers decided to implement it anyway. Only recently, the __proto__
property has been standardized in the ECMAScript 2015 language specification for web browsers to ensure compatibility, so will be supported into the future. It is deprecated in favor of {{jsxref("Object.getPrototypeOf")}}/{{jsxref("Reflect.getPrototypeOf")}} and {{jsxref("Object.setPrototypeOf")}}/{{jsxref("Reflect.setPrototypeOf")}} (though still, setting the [[Prototype]]
of an object is a slow operation that should be avoided if performance is a concern).
The __proto__
property can also be used in an object literal definition to set the object [[Prototype]]
on creation, as an alternative to {{jsxref("Object.create()")}}. See: object initializer / literal syntax.
var Circle = function () {}; var shape = {}; var 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); // true
var shape = function () {}; var p = { a: function () { console.log('aaa'); } }; shape.prototype.__proto__ = p; var circle = new shape(); circle.a(); // aaa console.log(shape.prototype === circle.__proto__); // true // or var shape = function () {}; var p = { a: function () { console.log('a'); } }; var circle = new shape(); circle.__proto__ = p; circle.a(); // a console.log(shape.prototype === circle.__proto__); // false // or function test() {}; test.prototype.myname = function () { console.log('myname'); }; var a = new test(); console.log(a.__proto__ === test.prototype); // true a.myname(); // myname // or var fn = function () {}; fn.prototype.myname = function () { console.log('myname'); }; var obj = { __proto__: fn.prototype }; obj.myname(); // myname
Note: that is two underscores, followed by the five characters "proto", followed by two more underscores.
The __proto__
getter function exposes the value of the internal [[Prototype]]
of an object. For objects created using an object literal, this value is {{jsxref("Object.prototype")}}. For objects created using array literals, this value is {{jsxref("Array.prototype")}}. For functions, this value is {{jsxref("Function.prototype")}}. For objects created using new fun
, where fun
is one of the built-in constructor functions provided by JavaScript ({{jsxref("Array")}}, {{jsxref("Boolean")}}, {{jsxref("Date")}}, {{jsxref("Number")}}, {{jsxref("Object")}}, {{jsxref("String")}}, and so on — including new constructors added as JavaScript evolves), this value is always fun.prototype
. For objects created using new fun
, where fun
is a function defined in a script, this value is the value of fun.prototype
. (That is, if the constructor didn't return an other object explicitly, or the fun.prototype
has been reassigned since the instance was created).
The __proto__
setter allows the [[Prototype]]
of an object to be mutated. The object must be extensible according to {{jsxref("Object.isExtensible()")}}: if it is not, a {{jsxref("Global_Objects/TypeError", "TypeError")}} is thrown. The value provided must be an object or {{jsxref("Global_Objects/null", "null")}}. Providing any other value will do nothing.
To understand how prototypes are used for inheritance, see guide article Inheritance and the prototype chain.
The __proto__
property is a simple accessor property on {{jsxref("Object.prototype")}} consisting of a getter and setter function. A property access for __proto__
that eventually consults {{jsxref("Object.prototype")}} will find this property, but an access that does not consult {{jsxref("Object.prototype")}} will not find it. If some other __proto__
property is found before {{jsxref("Object.prototype")}} is consulted, that property will hide the one found on {{jsxref("Object.prototype")}}.
Specification | Status | Comment |
---|---|---|
{{SpecName('ES2015', '#sec-additional-properties-of-the-object.prototype-object', 'Object.prototype.__proto__')}} | {{Spec2('ES2015')}} | Included in the (normative) annex for additional ECMAScript legacy features for Web browsers (note that the specification codifies what is already in implementations). |
{{SpecName('ESDraft', '#sec-additional-properties-of-the-object.prototype-object', 'Object.prototype.__proto__')}} | {{Spec2('ESDraft')}} |
{{Compat("javascript.builtins.Object.proto")}}
While the ECMAScript 2015 specification dictates that support for __proto__
is required only for web browsers (although being normative), other environments may support it as well for legacy usage.