我正在尝试使用setter在对象原型上设置可枚举属性。
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
除最后两行外,一切都按预期工作
我刚刚测试了节点v0.10.25中的代码。我不明白为什么属性标签不可枚举
作为一种解决方法,我在构造函数中使用Object.defineProperty而不是this
,但我想理解为什么javascript中的对象不能继承enuerable属性。
答案 0 :(得分:3)
问题是你的两个Object.defineProperty
调用定义了不同的属性:
this
上的一个值属性,即实例虽然原型上的那个是可枚举和可配置的,但实例属性不会“继承”这些描述符;他们将default to false
在新的描述符上。您需要明确设置它们:
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
});
}
});
答案 1 :(得分:1)
您可以在set函数中指定标记(通过在名为bar的Foo实例上创建成员来设置阴影标记)但不要将其设置为可强制或可配置尝试以下操作:
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
有关遮蔽成员,构造函数和原型的更多信息:https://stackoverflow.com/a/16063711/1641941
答案 2 :(得分:-1)
我认为您只能定义对象的属性,而不能定义原型或构造函数的属性,另请参阅this post。
为什么将object.defineProperty
置于构造函数中将工作:构造函数内的this
是一个对象。