Taha Ahmad
Taha Ahmad

Reputation: 559

Object prototype does not "live update"

I have the following piece of code:

var Test = function () {
};
Test.prototype.doSomething = function() {
  return "done";
};

Now, I create an object of Test

var t = new Test();
alert(t.doSomething());    // Correct alerts "done"

Now I add another method to the prototype:

Test.prototype.fly = function() { return "fly"; };
alert(t.fly());       // Correctly alerts "fly" (existing objects get "live udpated")

Now, I make the prototype point to a blank object:

Test.prototype = {};
alert(t.doSomething());    // Continues to alert "done", but why?
alert(t.fly());            // Continues to alert "fly", but why?

var t2 = new Test();
alert(t.doSomething());    // As expected, this does not work
  1. When I add a method to prototype, it reflects correctly on all new and existing objects

  2. When I "blank" out the prototype by doing <name>.prototype = {};, it only "blanks" out new instances, but not existing ones. Why?

Upvotes: 0

Views: 143

Answers (3)

WebServer
WebServer

Reputation: 1396

consider

function Foo(){}
Foo.prototype = {a:{"VMAddress":"@1234"}}

consider that Foo.prototype.a object has VMAddress "@1234" if you create object now then,

var f1 = new Foo();

now f1.a will point to the same object ie with Virtual Machine address "@1234" if you look

f1.a === Foo.prototype.a ;//prints tue

If you change prototype to some other value now,

Foo.prototype = {a:{"VMAddress":"@5678"}}

and if you create object now then,

var f2 = new Foo();

although

f2.a === Foo.prototype.a; //prints true because both point to same VM address @5678

but

f1.a === f2.a; //prints false

why?? because their VM address are different(one is @1234 and other is @5678) and infact they are different object

final verdict the prototype chain at the time of object creation decides what an object's prototype will be.

Upvotes: 0

Joseph
Joseph

Reputation: 119827

An analogy is this:

var a = {foo : 'bar'};
var b = a; //the same object as a
var c = a;
var d = a;

a.apple = 'orange';

a = 1;  //a === 1. b, c and d stay the same, pointing to the object with apple

What I did here is replace what a was pointing, but not the object itself.

When you added fly, you are modifying that single prototype object which all instances share, the object that Test.prototype is currently pointing to.

But when you assigned a blank object to Test.prototype, you modified what Test.prototype was pointing to. It does not modify what the existing instances are pointing to. But from this point on, any new instances will now use the new object on Test.prototype as their prototype object.

If you are familiar with C, I'd rather think of JS variables as pointers rather than references.

Upvotes: 4

Payou
Payou

Reputation: 371

I'm completing the previous answer, if you want reflect your changes on all instances you must update the prototype correctly.

Prototype property is an object and you can delete a propery with the reserved keyword 'delete'.

If you want delete 'doSomething' property :

delete Test.prototype.doSomething;

Upvotes: 0

Related Questions