Understanding javascript's prototype member

After looking Douglas Crockford's talks about javascript, I started experimenting to really understand javascript's prototype. If you have downloaded the presentation's slides, this is an illustration of slide 27. I've worked with the javascript interpreter included in the JDK6, based on Rhino. If you do this, just run $JAVA_HOME/bin/jrunscript and you get a prompt of the javascript interpreter. Each javascript function is given a prototype member when it is created. It is through this member that you can easily extend all objects of the same kind at once. For example you can easily extend every string object like this:
String.prototype.myNewMethod = function() { .... }
What intrigued me in the presentation is that you can assign a new object to the prototype member of an existing object. To illustrate this, let's work with the Gizmo and Hoozit from Douglas' presentation;
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); }
First let's create a Hoozit instance, and identify its toString method:
Hoozit.prototype.toString  //sun.org.mozilla.javascript.internal.InterpretedFunction@1201a25
my_hoozit = new Hoozit(1);
my_hoozit.toString();     //returns "hoozit 1" as expected
my_hoozit.toString;       //sun.org.mozilla.javascript.internal.InterpretedFunction@1201a25
my_hoozit.constructor;  //sun.org.mozilla.javascript.internal.InterpretedFunction@85af80
When accessing a function without calling it, the JDK6 javascript interpreter will display its id. Here we can see that my_hoozit.toString == Hoozit.prototype.toString, and if we update the toString method of the prototype, it impacts the already created instance:
Hoozit.prototype.toString = function () { return ('updated hoozit ' + this.id); }
Hoozit.prototype.toString  //sun.org.mozilla.javascript.internal.InterpretedFunction@c51355
my_hoozit.toString();        // returns 'updated hoozit 1'
my_hoozit.toString           //sun.org.mozilla.javascript.internal.InterpretedFunction@c51355
my_hoozit.constructor     //sun.org.mozilla.javascript.internal.InterpretedFunction@85af80
We see here that if we update the method in the prototype, each instance has the method updated. Now on to the strange part: as the prototype is a reference to an abject, you can assign an instance of another object to the prototype:
Hoozit.prototype = new Gizmo();
Hoozit.prototype.toString  //sun.org.mozilla.javascript.internal.InterpretedFunction@fa9cf
my_hoozit.toString(); //returns "updated hoozit 1"
How comes that although the method of the prototype has been changed, the call on the existing object hasn't been adapted? The thing is that when my_hoozit was created, it has been assigned a prototype member that is a pointed the Hoozit.prototype. When we assigned an instance of a Gizmo to Hoozit.prototype, it didn't change the pointer of the already instanciated Hoozit, which still points to the initial Hoozit.prototype object. We can see it like this:
my_hoozit.toString       //sun.org.mozilla.javascript.internal.InterpretedFunction@c51355
my_hoozit.constructor  //sun.org.mozilla.javascript.internal.InterpretedFunction@85af80
You can see that my_hoozit.toString still is the method with "id" c51355. Now if we instanciate a new Hoozit, its prototype member will point to the current Hoozit.prototype:
second_hoozit = new Hoozit(2);
second_hoozit.toString(); //returns "gizmo 2"
second_hoozit.toString    //sun.org.mozilla.javascript.internal.InterpretedFunction@fa9cf
If I adapt the Hoozit.prototype, it will only affect the second_hoozit, and not my_hoozit:
Hoozit.prototype.toString = function () { return ('again updated hoozit ' + this.id); }
Hoozit.prototype.toString  //sun.org.mozilla.javascript.internal.InterpretedFunction@a3bcc1

my_hoozit.toString();         // returns "updated hoozit 1"
my_hoozit.toString            //sun.org.mozilla.javascript.internal.InterpretedFunction@c51355

second_hoozit.toString()   //again updated hoozit 2
second_hoozit.toString     //sun.org.mozilla.javascript.internal.InterpretedFunction@a3bcc1
Now, if you had a toString method to the second_hoozit, it is added to the object itself:
second_hoozit.toString=function(){ return "my second_hoozit method"}
second_hoozit.toString      //sun.org.mozilla.javascript.internal.InterpretedFunction@1bd4722
Hoozit.prototype.toString  //sun.org.mozilla.javascript.internal.InterpretedFunction@a3bcc1
In standard javascript you don't have access to an instance's prototype, though with mozilla you can access it through the __proto__ member. This lets us illustrate further:
second_hoozit.toString                //sun.org.mozilla.javascript.internal.InterpretedFunction@1bd4722
second_hoozit.__proto__.toString //sun.org.mozilla.javascript.internal.InterpretedFunction@a3bcc1
Hoozit.prototype.toString            //sun.org.mozilla.javascript.internal.InterpretedFunction@a3bcc1
my_hoozit.__proto__.toString     //sun.org.mozilla.javascript.internal.InterpretedFunction@c51355
I hope this helped you understand the mechanism behind javascript's prototype. PS: Special thanks go to Richard Cornford and Isaac Schlueter for their answers in com.lang.javascript!