mozilla
Your Search Results

    Object.prototype.__proto__

    Warning: Mutating the [[Prototype]] of an object is, by the nature of how modern JavaScript engines optimize property accesses, a very slow operation, in every browser and JavaScript engine. The effects on performance of mutating prototypes are subtle and far-flung, and are not limited to simply the time spent in obj.__proto__ = ..., but may extend to any code that has access to any object whose [[Prototype]] has been mutated. If you care about performance you should avoid mutating the [[Prototype]] of an object. Instead, create the object with the desired [[Prototype]] using Object.create().

    Warning: While support for Object.prototype.__proto__ already exists today in most browsers, its behavior has only been standardized recently in the new ECMAScript 6 specification. If you need support for pre-ES6 browsers, it is reccomended that only Object.getPrototypeOf() be used instead.

    Summary

    The __proto__ property of Object.prototype is an accessor property (a getter function and a setter function) that exposes the internal [[Prototype]] (either an object or null) of the object through which it is accessed.

    The use of __proto__ is controversial, and has been discouraged by many. It was never originally included in the EcmaScript language spec, but modern browsers decided to implement it anyway. Today, the __proto__ property has been standardized in the ECMAScript 6 language specification and will be supported into the future. Still, mutating 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 Object.create(). See: object initializer / literal syntax.

    Syntax

    var shape = {}, circle = new Circle();
    
    // Set the object prototype
    shape.__proto__ = circle;
    // Get the object prototype
    console.log(shape.__proto__ === circle); // true
    

    Note: that is two underscores, followed by the five characters "proto", followed by two more underscores.

    Description

    The __proto__ getter function exposes the value of the internal [[Prototype]] of an object. For objects created using an object literal, this value is Object.prototype. For objects created using array literals, this value is Array.prototype. For functions, this value is Function.prototype. For objects created using new fun, where fun is one of the built-in constructor functions provided by JavaScript (Array, Boolean, Date, Number, Object, String, and so on — including new constructors added as JavaScript evolves), this value is 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 at the time new fun is evaluated. (That is, if a new value is assigned to fun.prototype, previously-created fun instances will continue to have the previous value as their [[Prototype]], and subsequent new fun calls will use the newly-assigned value as their [[Prototype]].)

    The __proto__ setter allows the [[Prototype]] of an object to be mutated. The object must be extensible according to Object.isExtensible(): if it is not, a TypeError is thrown. The value provided must be an object or 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 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 find it. If some other __proto__ property is found before Object.prototype is consulted, that property will hide the one found on Object.prototype.

    var noProto = Object.create(null);
    
    console.log(typeof noProto.__proto__); // undefined
    console.log(Object.getPrototypeOf(noProto)); // null
    
    noProto.__proto__ = 17;
    
    console.log(noProto.__proto__); // 17
    console.log(Object.getPrototypeOf(noProto)); // null
    
    var protoHidden = {};
    Object.defineProperty(protoHidden, "__proto__",
                          { value: 42, writable: true, configurable: true, enumerable: true });
    
    console.log(protoHidden.__proto__); // 42
    console.log(Object.getPrototypeOf(protoHidden) === Object.prototype); // true
    

    Examples

    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:

    function Cow() {
      /* initialise instance */
    }
    
    // Assign a new object to __proto__
    fred.__proto__ = Cow.prototype;
    

    Now fred inherits directly from Cow.prototype instead of Employee.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__ =
      Object.create(null, // [[Prototype]]
                    { hi: { value: function() { alert('hi'); } } });
    
    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).

    Specifications

    Specification Status Comment
    ECMAScript 6 (ECMA-262)
    The definition of 'Object.prototype.__proto__' in that specification.
    Draft Included in the (normative) annex for additional ECMAScript features for Web browsers (note that the specification codifies what is already in implementations).

    Browser compatibility

    Note: While the ES6 specification dictates that support for __proto__ is required for web browsers, it is not required in other environments (although it is encouraged as normative). If your code must support non-web browser environments, it is reccomended to use Object.getPrototypeOf() and Object.setPrototypeOf() instead.

    Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
    Basic support (Yes) (Yes) 11 (Yes) (Yes)
    Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
    Basic support (Yes) (Yes) (Yes) (Yes) (Yes) (Yes)

    See also

    Document Tags and Contributors

    Last updated by: Mingun,