Search code examples
javascriptprototype

How to set a property of a prototype object for a single class


Say I change the object prototype like so:

Object.prototype.test = {val: 5, abc: 8};

Then I change a property of test for Array:

Array.prototype.test.abc = 20;

Then if I print the base test variable:

console.log(Object.prototype.test); // {val: 5, abc: 20}
console.log(({}).test);        // {val: 5, abc: 20}
console.log(([]).test);       // {val: 5, abc: 20}

How do I still have arrays inherit val as 5, but have an abc value of 20 without affecting Object's prototype


Solution

  • In your example Array.protoype does not have its own test property. So when you try to access it with Array.prototype.test.abc = 20; it looks up the prototype chain and find the .test object on Object.prototype and sets its .abc value to 20.

    You can give Array.prototype it's own property test with something like:

    Object.prototype.test = {val: 5, abc: 8};
    
    Array.prototype.test = Object.assign({}, Object.prototype.test)
    Array.prototype.test.abc = 20;
    
    console.log(({}).test.abc);       // 8
    console.log(([]).test.abc);       // 20

    You could also link the test object from Array to Object so properties not found on Array.prototype.test will defer up the chain to Object.prototype.test, although this starts to get confusing:

    Object.prototype.test = {val: 5, abc: 8};
    
    Array.prototype.test = Object.create(Object.prototype.test)
    Array.prototype.test.abc = 20;
    
    console.log(([]).test.abc);      // shadows with it's own abc
    Object.prototype.test.abc = 500  // changes in object have no effect
    console.log(([]).test.abc);      // still 20
    
    console.log(([]).test.val);      // no val on Array's test so it defers to object prototype
    Object.prototype.test.val = 100  // changing object changes array
    console.log(([]).test.val); 

    …not that I really recommend any of this beyond test and exploring the ecosystem.