Non-standard
An Object's __proto__
property references the same object as its internal [[Prototype]]
(often referred to as "the prototype"), which may be an object or, as in the default case of Object.prototype.__proto__,
null
. This property is an abstraction error, because a property with the same name, but some other value, could be defined on the object too. If there is a need to reference an object's prototype, the preferred method is to use Object.getPrototypeOf
.
Property of Object |
|
---|---|
Implemented in | JavaScript ? |
ECMAScript Edition | - |
A __proto__
pseudo property has been included in §B.3.1 of the draft ECMAScript ed. 6 specification (note that the specification codifies what is already in implementations and what websites may currently rely on).
Syntax
var proto = obj.__proto__;
Note: that is two underscores, followed by the five characters "proto", followed by two more underscores.
Description
When an object is created, its __proto__
property is set to reference the same object as its internal [[Prototype]]
(i.e. its constructor's prototype
object). Assigning a new value to __proto__
also changes the value of the internal [[Prototype]]
property, except where the object is non–extensible.
To understand how prototypes are used for inheritance, see the MDN article Inheritance and the prototype chain.
Example
In the following, a new instance of Employee
is created, then tested to show that its __proto__
is the same object as its constructor's prototype
.
// Declare a function to be used as a constructor function Employee() { /* initialise instance */ } // Create a new instance of Employee var fred = new Employee(); // Test equivalence fred.__proto__ === Employee.prototype; // true
At this point, fred
inherits from Employee
, however assigning a different object to fred.__proto__
can change that:
// Assign a new object to __proto__ fred.__proto__ = Object.prototype;
Now fred
no longer inherits from Employee.prototype
, but directly from Object.prototype
, and loses the properties it originally inherited from Employee.prototype
.
However, this only applies to extensible objects, a non–extensible object's __proto__
property cannot be changed:
var obj = {}; Object.preventExtensions(obj); obj.__proto__ = {}; // throws a TypeError
Note that even Object.prototype
's __proto__
property can be redefined as long as the chain leads to null:
var b = {}; Object.prototype.__proto__ = { hi: function () {alert('hi');}, __proto__: null }; b.hi();
If Object.prototype
's __proto__
had not been set to null
, or had not been set to another object whose prototype chain did not eventually lead explicitly to null
, a "cyclic __proto__ value" TypeError would result since the chain must eventually lead to null
(as it normally does on Object.prototype
).