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.
The problem is that your two Object.defineProperty
call define different properties:
this
, ie 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
});
}
});
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
I think you can only define properties for an object, not on a prototype or a constructor function, see also this post .
That why putting the object.defineProperty
inside the constructor will work: this
inside the constructor is an object.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.