Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Setting enumerable property on object prototype

I'm trying to set enumerable property, with setter, on an object prototype.

function Foo(){}
Object.defineProperty(Foo.prototype, 'tag', {
    enumerable: true, configurable: true,
    set: function(x){ 
        if(typeof(x) == "string") {
            Object.defineProperty(this, 'tag', {value: x});
        }
    }
});
var bar = new Foo();

bar.tag = 7;     console.log(bar.tag); // undefined
bar.tag = "baz"; console.log(bar.tag); // "baz"

console.log(bar); // {}
console.log(bar.propertyIsEnumerable('tag')); // false

Everything work as expected, except the last two line.
I just tested the code in node v0.10.25 . I don't understand why the property tag isn't enumerable.
As a workaround, I'm using Object.defineProperty in the constructor against this instead of Foo.prototype, but I would like to understand why object in javascript can't inherit from enuerable properties.

like image 562
gkr Avatar asked Oct 30 '25 00:10

gkr


1 Answers

The problem is that your two Object.defineProperty call define different properties:

  • One setter property on the prototype
  • One value property on each this, i.e. instance

While the one on the prototype is enumerable and configurable, the instance property will not "inherit" these descriptors; and they will default to false on the new descriptor. You will need to set them explicitly:

Object.defineProperty(Foo.prototype, 'tag', {
     enumerable: true, configurable: true,
     set: function(x){ 
         if (typeof(x) == "string")
             Object.defineProperty(this, 'tag', {
                 enumerable:true, configurable:true, // still non-writable
                 value: x
             });
     }
});
like image 71
Bergi Avatar answered Nov 01 '25 15:11

Bergi