Search code examples
javascriptprototypegetter-setter

In JavaScript, is it possible to bypass a setter?


I have an object o with prototype p:

var p = {}
var o = Object.create(p)

It is possible to add a property a to the object o, and then add a setter of the same name to the prototype p:

o.a = 1
Object.defineProperty(p, 'a', {set: function(value) {}});

console.log(o.a);  // 1

However, if we try to add the property after the setter, it is not added to o - the setter is called instead:

Object.defineProperty(p, 'a', {set: function(value) {}});
o.a = 1

console.log(o.a);  // undefined

Is it possible to define the setter first, but then bypass it to add the property a directly to o?


Solution

  • You can use defineProperty again and set writable to true. You'll probably also want to set enumerable and configurable since they default to false. You don't need to set the value as that defaults to undefined, but I think it's clearer with it.

    var p = {}
    var o = Object.create(p)
    Object.defineProperty(p, 'a', {set: function(value) {console.log("value:", value)}})
    
    o.a = "test" // logs "value: test"
    
    // override setter
    Object.defineProperty(o, 'a', {value:undefined, writable:true, enumerable:true, configurable:true})
    
    console.log(o.a);  // undefined
    
    o.a = 1
    console.log(o.a);  // 1
    console.log(Object.keys(o))