Javascript: Prototype modification does not affect existing instances

I created 2 copies of the prototype, changed the function in the prototype, the changes were reflected in both copies (Great). However, when I modified the prototype by deleting the function, the function still existed for existing instances.

function A() { this.name = "cool"; } A.prototype = { howCool: function() { return this.name + "er"; } }; var a1 = new A(), a2 = new A(); a1.name = "hot"; //line1 console.log(a1.howCool()); //line2 console.log(a2.howCool()); A.prototype = {}; //line3 console.log(a1.howCool()); //line4 var a3 = new A(); console.log(a3.howCool()); 

Lines 1 and 2 work as expected, and after setting protoype back to empty line 4 shows undefined, which is expected. line 3, however, still shows the definition of the function.

+7
javascript prototype ecmascript-6
source share
4 answers

Essentially, you reassign the prototype property to function A to point to a new object. This does not affect the old object and thus does not affect previous instances.

Here is an illustration of what is happening.

After executing this code:

 function A() { this.name = "cool"; } A.prototype = { howCool: function() { return this.name + "er"; } }; var a1 = new A(), a2 = new A(); 

The situation is as follows:

before

Then after executing this code:

 A.prototype = {}; var a3 = new A(); 

A.prototype points to a new object, but the [[Prototype]] property for old instances still points to the old object.

after

If you want to delete this method, you must edit the original object, and not point to a new one.

To actually remove the howCool() method from the prototype, something like this would work:

 delete A.prototype.howCool 

What will give:

finally

Now, any future instances, such as a3 and previous ones, will still point to the same object, but this object will not have the howCool() method.

+5
source share

Well, if you change the prototype, it will affect the old instances, but if you create a new one, it will not affect the old instances.

So when you write:

 A.prototype = {}; //line3 console.log(a1.howCool); 

The a1.__proto__ object still points to the starting A.prototype , so it does not register undefined .

And then when you write:

 //line4 var a3 = new A(); console.log(a3.howCool()); 

The new a3 instance uses the new A.prototype created, so you got "undefined".

+1
source share

Try using the delete operator

 function A(){ this.name = "cool"; } A.prototype = { howCool : function(){ return this.name + "er"; } }; var a1 = new A(), a2 = new A(); a1.name = "hot"; //line1 console.log(a1.howCool); //line2 console.log(a2.howCool); delete A.prototype.howCool; //line3 console.log(a1.howCool); //line4 var a3 = new A(); console.log(a3.howCool); 
0
source share

Here is a possible explanation:
(Note: the explanation below is only for experimentation and conceptual understanding, since __proto__ should be avoided in production code)

As you know, there is a connection between the object (in this case, a1) and the prototype of the constructor function (in this case, A) from which the object is created. This link is called __proto__ or dunder proto. Therefore, in this case it can be seen as a1.__proto__ .

Now what happens when you say A.prototype = {}; , at this time, the a1 object was already constructed, and it points to A.prototype through this link.

Since Javascript is a garbage collector, just setting A.prototype to {} does not clear the old protoytpe object directly, which means the older object is still delayed. Therefore, when you say console.log(a1.howCool()); , howCool is in a lingering object.

So, if you change your line3 as follows:

// line3

 console.log(a1.__proto__); a1.__proto__ = {}; console.log(a1.howCool()); 

You can see the old prototype object and howCool () inside it in the console window in the console.log(a1.__proto__); line console.log(a1.__proto__); However, if you set a1.__proto__ = {}; , then console.log(a1.howCool()); cannot find the object, and the Cool () method will not be found (since now it is set to an empty object).

So, just setting A.prototype to {} does not achieve the same effect as a.__proto__ = {}.

Therefore, the result that you see.

Hope this helps.

0
source share

All Articles