Relation between [[Prototype]] and prototype in JavaScript

蹲街弑〆低调 提交于 2019-11-27 17:21:26
JacquesB

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!

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]]:

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

In addition to olavk's answer: Some JavaScript implementations (eg mozilla's) allow to access the [[Prototype]] property directly...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!