How to manipulate properties of the object prototype?

112 Views Asked by At

I'm trying to do the following:

function SomeFunctionConstructor() {
   this.someMainVariable = "someValue";
   this.manipulatePrototype = () => {
     this.someProtoVariable = "some new value";
   }
}

SomeFunctionConstructor.prototype.someProtoVariable = "Some proto value";


var someInstance = new SomeFunctionConstructor();

Now, if I console.log(someInstance), it prints:

{
  someMainVariable: 'someValue',
  manipulatePrototype: [Function] 
}

And now, when I do someInstance.manipulatePrototype() and then console.log(someInstance), it prints:

{
  someMainVariable: 'someValue',
  manipulatePrototype: [Function],
  someProtoVariable: 'some new value' 
}

Why does it create a new someProtoVariable directly on the instance instead of updating the someProtoVariable on the prototype? :(

2

There are 2 best solutions below

0
On

i think you are confusing between an instance and the prototype . and instance cant over the object prototype by design. if this would happens then every instance will be able to destroy the prototype chain and effect all other instances that are built from this prototype

if you print someInstance.someProtoVariable without calling manipulatePrototype then you will get the old value.

and after you will get the new value .
this.someProtoVariable did override the default value for the instance but didn`t override the prototype itself

you can read more about prototype here Inheritance_and_the_prototype_chain

1
On

If you really want to modify a property on an object's prototype, you can either refer to the prototype directly via the constructor:

SomeConstructor.prototype.property = newValue;

or use Object.getPrototypeOf() on an instance:

Object.getPrototypeOf(someInstance).property = newValue;

Now, in general things can get kind-of complicated, because an instance may have more than one object in its prototype chain. Exactly what you might want in such a case is up to your application.

Note that changing the property value on the prototype will have the effect of making the property have the new value on all instances.

You could add a setter function to the prototype to do this automatically:

Object.defineProperty(SomeConstructor.prototype, "property", {
  value: someInitialValue,
  set: function(value) {
    Object.getPrototypeOf(this)["@property"] = value;
  },
  get: function() {
    return Object.getPrototypeOf(this)["@property"];
  }
});

That uses another prototype property called "@property" (could be any name, or better yet a Symbol instance) to store the apparent value of "property". With that,

someInstance.property = newValue;

would make a call to the setter function and update the "@property" value on the prototype.