Reputation: 469
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.
Upvotes: 3
Views: 2282
Reputation: 665276
The problem is that your two Object.defineProperty
call define different properties:
this
, i.e. instanceWhile 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
});
}
});
Upvotes: 4
Reputation: 39320
You re assign tag in the set function (shadowing tag by creating the member on the Foo instance named bar) but don't set it to enumarable or configurable try the following:
function Foo(){}
Object.defineProperty(Foo.prototype, 'tag', {
enumerable: true, configurable: true,
set: function(x){
if(typeof(x) == "string") {
Object.defineProperty(this, 'tag', {
value: x,
enumerable: true
});
}
}
});
var bar = new Foo();
bar.tag = 7; console.log(bar.tag); // undefined
bar.tag = "baz"; console.log(bar.tag); // "baz"
console.log(bar); // { tag="baz" }
console.log(bar.propertyIsEnumerable('tag')); // true
More info about shadowing members, constructor functions and prototype: https://stackoverflow.com/a/16063711/1641941
Upvotes: 2