Why do existing objects keep prototype methods after prototype replacement in JavaScript

I’m encountering a puzzling issue with JavaScript prototypes. I defined a constructor function and added methods to its prototype. After creating instances from it, everything worked perfectly when I added new methods - all instances could use them immediately.

However, here’s the strange part: when I replaced the prototype with an empty object, the old instances still retained access to the original methods. New instances made after the replacement do not have access to those methods, which is understandable.

function Car() {
  this.brand = "Toyota";
}

Car.prototype = {
  getInfo: function() {
    return this.brand + " vehicle";
  }
};

var car1 = new Car();
var car2 = new Car();

car1.brand = "Honda";
console.log(car1.getInfo()); // works fine
console.log(car2.getInfo()); // works fine

Car.prototype = {};

console.log(car1.getInfo()); // still works but why?

var car3 = new Car();
console.log(car3.getInfo()); // undefined as expected

Why do car1 and car2 still retain the getInfo method even after I removed the prototype? I assumed all instances would point to the same prototype reference.

when you create an obj, it links to the prototype at that time, not to the var which is the constructor’s prototype. so when you replace it, old instances point to the original proto in memory. new objs will use the updated one.

Here’s what’s happening: every instance has an internal [[Prototype]] link that gets set when you create the object with new. This link points to whatever Car.prototype was at that exact moment - it’s a permanent connection. When you do Car.prototype = {}, you’re just changing where the prototype property points, but existing instances still have their original [[Prototype]] links to the old prototype object. The original prototype with getInfo is still in memory because car1 and car2 are referencing it. Only new instances will use the updated prototype. That’s why tweaking existing prototype properties affects all instances, but completely replacing the prototype only hits future ones.

This happens because JavaScript links each instance directly to the prototype object that existed when you created it. When you make car1 and car2, they connect to that specific prototype object in memory - not to the Car.prototype property itself. So when you replace Car.prototype, you’re just changing where that property points. The existing objects still reference the original prototype object, which is still sitting in memory. Think of it like the instances have their own private link to the original prototype. That’s why prototype pollution works and why changing existing prototype objects hits all instances, but swapping out the entire prototype only affects new instances you create later.

This topic was automatically closed 6 hours after the last reply. New replies are no longer allowed.