explanations about MyObject.prototype = new OtherObject()

R

rb

Hi,


I'm experimenting with javascript Objects' prototypes. There is one
behaviour which I don't understand when I update the prototype with
another object instance. I hope someone here can explain this
behaviour. Here's some code (inspired by Douglas Crockford's
presentation at Yahoo and available online):

// Define entities
/***************/
function Gizmo(id) { this.id= id; }
Gizmo.prototype.toString = function () { return ('gizmo ' +
this.id); }

function Hoozit(id) { this.id = id };
Hoozit.prototype.toString = function () { return ('hoozit ' +
this.id); }

// Instanciate an Hoozit
/********************/
my_hoozit = new Hoozit(1);
my_hoozit.toString(); //returns "hoozit 1" as expected

//Update Hoozit.prototype and get the expected result
/*************************************************/
Hoozit.prototype.toString = function () { return ('updated hoozit ' +
this.id); }
my_hoozit.toString(); //returns 'updated hoozit 1',

// Update Hoozit.prototype to another object's instance
//*************************************************/
Hoozit.prototype = new Gizmo();
my_hoozit.toString(); //returns "updated hoozit 1", although the
prototype has been changed.
// This doesn't call the toString from the newly set prototype.


//Update Hoozit.prototype with a new function
/*****************************************/
Hoozit.prototype.toString = function () { return ('again updated
hoozit ' + this.id); }
my_hoozit.toString(); //returns 'updated hoozit 1',
//This doesn't work anymore!

It seems as if the toString method has been moved to the instance when
assigning the new Gizmo to Hoozit.prototype. Is that correct? Why is
that?

Thanks

Raph
 
R

Richard Cornford

On Feb 5, 1:31 pm, rb wrote:
It seems as if the toString method has been moved to the instance when
assigning the new Gizmo to Hoozit.prototype. Is that correct?
<snip>

No, at the point of creating an object with a constructor the value of
the public - prototype - property of the constructor is copied to an
internal - [[Prototype]] - property, and it is that internal property
that is used when resolving property names against the object (if
necessary). Thus the object assigned as the prototype of the
constructed object is fixed at the point of creating the object, and
cannot be changed, but the object that is used as the prototype can
still be modified.

Richard.
 
I

Isaac Schlueter

It seems as if the toString method has been moved to the instance when
assigning the new Gizmo to Hoozit.prototype. Is that correct? Why is
that?

Your problem has to do with changing some references and not others.

my_hoozit = new Hoozit(1);
my_hoozit.toString(); //returns "hoozit 1" as expected

So, Hoozit (the function) has a property called "prototype," that
links to an object. That object reference is copied to all objects
constructed by Hoozit at the time of construction.

While it's not standard, I like using the __proto__ object to discuss
this topic, so we can say that
my_hoozit.__proto__ = Hoozit.prototype
at the time of construction.
//Update Hoozit.prototype and get the expected result
/*************************************************/
Hoozit.prototype.toString = function () { return ('updated hoozit ' +
this.id); }
my_hoozit.toString(); //returns 'updated hoozit 1',

You've changed the "toString" member of the Hoozit.prototype object.
Since my_hoozit.__proto__ links to the same object, you've also
changed the my_hoozit.__proto__.toString.

Hoozit.prototype = new Gizmo();
Because you've copied out the root object reference, Hoozit.prototype !
== my_hoozit.__proto__.


Here's a simplified example:

var a={ foo:'bar' }; // set a to a new object with member foo
var b=a; // make a new reference named b that points to the same
object as a.
alert(b.foo); // bar
a.foo='asdf'; // change the member
alert(b.foo); // asdf
a={foo:'quux'}; // set a to a new object.
alert(b.foo); // still asdf. b and a don't point at the same object
any more.


Another approach would have been this:

var p=new Gizmo();
for(var i in p) {
Hoozit.prototype = p;
};

That would have updated the prototype object, without making the whole
prototype link to a new object.
 
R

rb

It seems as if the toString method has been moved to the instance when
assigning the new Gizmo to Hoozit.prototype. Is that correct? Why is
that?

Your problem has to do with changing some references and not others.

my_hoozit = new Hoozit(1);
my_hoozit.toString(); //returns "hoozit 1" as expected

So, Hoozit (the function) has a property called "prototype," that
links to an object. That object reference is copied to all objects
constructed by Hoozit at the time of construction.

While it's not standard, I like using the __proto__ object to discuss
this topic, so we can say that
my_hoozit.__proto__ = Hoozit.prototype
at the time of construction.
//Update Hoozit.prototype and get the expected result
/*************************************************/
Hoozit.prototype.toString = function () { return ('updated hoozit ' +
this.id); }
my_hoozit.toString(); //returns 'updated hoozit 1',

You've changed the "toString" member of the Hoozit.prototype object.
Since my_hoozit.__proto__ links to the same object, you've also
changed the my_hoozit.__proto__.toString.
Hoozit.prototype = new Gizmo();

Because you've copied out the root object reference, Hoozit.prototype !
== my_hoozit.__proto__.

Here's a simplified example:

var a={ foo:'bar' }; // set a to a new object with member foo
var b=a; // make a new reference named b that points to the same
object as a.
alert(b.foo); // bar
a.foo='asdf'; // change the member
alert(b.foo); // asdf
a={foo:'quux'}; // set a to a new object.
alert(b.foo); // still asdf. b and a don't point at the same object
any more.

Another approach would have been this:

var p=new Gizmo();
for(var i in p) {
Hoozit.prototype = p;

};

That would have updated the prototype object, without making the whole
prototype link to a new object.


Thanks for your answers. I've played further with the Rhino
javascript engine from the JDK6 and illustrated all this at http://
www.myowndb.com/blog/?p=26

Cheers

Raph
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,432
Messages
2,571,680
Members
48,796
Latest member
Greg L.

Latest Threads

Top