在对象原型上设置可枚举属性

时间:2014-02-04 07:22:19

标签: javascript node.js

我正在尝试使用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属性。

3 个答案:

答案 0 :(得分:3)

问题是你的两个Object.defineProperty调用定义了不同的属性:

  • 原型上的一个setter属性
  • 每个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是一个对象。

相关问题