When evaluating the value of
myObject.myMember
My guess is that javascript will try to look up the “myMember” entry in:
myObject
myObject.constructor.prototype
myObject.constructor.prototype.constructor.prototype
myObject.constructor.prototype.constructor.prototype.constructor.prototype
.......
until succeed.
The following code seems to validate my guess
var MyClass1=function(){
this.key1="value1";
};
var myObject=new MyClass1();
MyClass1.prototype.key2="value2";
console.log(myObject.constructor.prototype.key2=="value2"); //true
console.log(myObject.key2=="value2"); //true :)
But the following code proves my guess is wrong
var MyClass1=function(){
this.key1="value1";
};
var MyClass2=function(){
this.key2="value2";
};
var myObject=new MyClass1();
MyClass1.prototype=new MyClass2();
console.log(myObject.constructor.prototype.key2=="value2");//true
console.log(myObject.key2=="value2");// false! why?
What is the actual algorithm by which javascript looks up a member of an object through its prototype chain?
It’s because you called
MyClass1.prototype=new MyClass2();after creating an instance ofMyClass1.Let’s inspect the operation
var myObject=new MyClass1()The
newoperator ( http://es5.github.com/#x11.2.2 ) calls the[[Construct]]internal method ofmyClass1(pseudo-code, of course.)This is the skimmed version of what happens inside
[[Construct]]( http://es5.github.com/#x13.2.2 ) calls (obviously pseudo-code):By “actual prototype”, I mean not the
fun.prototypeyou’re used of seeing – that prototype looks forward, to instances we will create. The[[Prototype]]of an object is the properties inherited to it, it’s its past.That can be retrieved by using
Object.getPrototypeOf, and in some implementations can be set using the non-standardobj.__proto__.Okay, now that we’ve established how objects are created using
new, why doesn’t your example work?Replacing
MyClass1.prototypeafter you createmyObjectwill break the link that was between the two.MyClass1has moved to the dark side, it has completely changed, a new object now replaces it, andmyObjectwants nothing to do with that.Before the change,
myObject.__proto__ === MyClass1.prototype, it holds a reference to the objectMyClass1.prototype. Once you’ve changed the objectMyClass1.prototype,myObject.__proto__will continue referencing that old object instead of the new one.The answer is pretty much done. To rehash – The
[[Construct]]function establishes a link betweenMyClass1.prototypeandmyObject. That link doesn’t change when you replaceMyClass1.prototype, somyObjectwill happily live with the object it was originally linked to.In case you’re still curious about how property fetching is done: http://es5.github.com/#x8.12.2 I warn you though, spec-language is tedious to read.