Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Relation between [[Prototype]] and prototype in JavaScript

From http://www.jibbering.com/faq/faq_notes/closures.html :

Note: ECMAScript defines an internal [[prototype]] property of the internal Object type. This property is not directly accessible with scripts, but it is the chain of objects referred to with the internal [[prototype]] property that is used in property accessor resolution; the object's prototype chain. A public prototype property exists to allow the assignment, definition and manipulation of prototypes in association with the internal [[prototype]] property. The details of the relationship between to two are described in ECMA 262 (3rd edition) and are beyond the scope of this discussion.

What are the details of the relationship between the two? I've browsed through ECMA 262 and all I've read there is stuff like:

The constructor’s associated prototype can be referenced by the program expression constructor.prototype,

Native ECMAScript objects have an internal property called [[Prototype]]. The value of this property is either null or an object and is used for implementing inheritance.

Every built-in function and every built-in constructor has the Function prototype object, which is the initial value of the expression Function.prototype

Every built-in prototype object has the Object prototype object, which is the initial value of the expression Object.prototype (15.3.2.1), as the value of its internal [[Prototype]] property, except the Object prototype object itself.

From this all I gather is that the [[Prototype]] property is equivalent to the prototype property for pretty much any object. Am I mistaken?

like image 567
Claudiu Avatar asked Dec 20 '08 11:12

Claudiu


People also ask

What is the difference between prototype and [[ prototype ]]?

Function. prototype is itself is nothing but an object which is constructed from another system constructor called [[Object]] . So, [[Object]] is the constructor of Function. prototype .

Which of the following has the special hidden property proto proto [[ prototype ]] prototype?

[[Prototype]] In JavaScript, objects have a special hidden property [[Prototype]] (as named in the specification), that is either null or references another object. That object is called “a prototype”: When we read a property from object , and it's missing, JavaScript automatically takes it from the prototype.

What is the difference between an internal prototype and the .prototype property of a function?

All the objects have proto property. The prototype gives access to the prototype of function using function. proto gives access to the prototype of the function using the object.

What does __ proto __ mean in JavaScript?

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.


2 Answers

I believe you are right in most cases.

Every object has a hidden [[Prototype]] property, which is used for inheritance. Functions additionally have a public prototype property, which is used only when the function is used as constructor: When an object is constructed using new, the [[Prototype]] property of the new object is set to the prototype property of the function that was used as constructor.

E.g.

function C() {}
C.prototype = P1;  
var obj = new C();  // obj.[[Prototype]] is now P1.

You can get the [[Prototype]] property using Object.getPrototypeOf(<obj>). (This method is specified in ECMAScript 5. Older versions of JavaScript does not have any standard way of reading [[Prototype]]).

You can usually get to the prototype through the constructor, e.g.:

obj.constructor.prototype == Object.getPrototypeOf(obj) 

But this is not always the case, since the prototype property of the constructor function can be reassigned, but the [[Prototype]] of an object cannot be reassigned after the object is created. So if you do:

C.prototype = P2;

then

obj.constructor.prototype != Object.getPrototypeOf(obj)

Because the prototype of C is now P2, but [[Prototype]] of obj is still P1.

Note that it is only functions that have a prototype property. Note also that the prototype property of a function is not the same as the [[Prototype]] property of the function!

like image 86
JacquesB Avatar answered Sep 28 '22 07:09

JacquesB


To answer your question directly: logically it is an object's private copy of the prototype property of its constructor. Using metalanguage this is how objects are created:

// not real JS

var Ctr = function(...){...};
Ctr.prototype = {...}; // some object with methods and properties

// the object creation sequence: var x = new Ctr(a, b, c);
var x = {};
x["[[prototype]]"] = Ctr.prototype;
var result = Ctr.call(x, a, b, c);
if(typeof result == "object"){ x = result; }
// our x is fully constructed and initialized at this point

At this point we can modify the prototype, and the change will be reflected by all objects of the class, because they refer to the prototype by reference:

Ctr.prototype.log = function(){ console.log("...logging..."); };

x.log();  // ...logging..

But if we change the prototype on the constructor, already created objects will continue referring to the old object:

Ctr.prototype = {life: 42};
// let's assume that the old prototype didn't define "life"

console.log(x.life);  // undefined
x.log();              // ...logging...

In the full accordance with the standard [[prototype]] is not available, but Mozilla extends the standard with __proto__ property (read-only), which is exposing the normally hidden [[prototype]]:

  • the Mozilla's documentation
  • overview of Mozilla's extensions: __count__, __proto__, __parent__

Again, __proto__ can be legalized in the next ES3.1 standard.

like image 24
Eugene Lazutkin Avatar answered Sep 28 '22 09:09

Eugene Lazutkin