Object.defineProperties()

时间:2015-08-18 13:40:08

标签: javascript defineproperty

向对象添加多个属性时,使用Object.defineProperties()添加它们通常会产生比逐个或成组添加它们更清晰,更易读的代码。

但是,如果属性引用另一个属性,则Object.defineProperties()无法处理它。考虑一个虚拟的例子:

var foo = {};
Object.defineProperties(foo, {
    "one" : {value: 1, enumerable: true},
    "two" : {value: foo.one + 1, enumerable: true}
})
console.log(foo); // { one: 1, two: NaN }

var bar = {};
Object.defineProperties(bar,{
    "one" : {value: 1, enumerable: true}
}); 
Object.defineProperties(bar,{
    "two" : {value: bar.one + 1, enumerable: true}
});

console.log(bar); // { one: 1, two: 2 }

现在很明显,第二种解决方案始终有效。但是,可以假设第一个 也可以工作,因为它似乎就像另一个的简写,建议顺序处理无论如何,物业。

我没有找到关于此的明确文档。

所以问题是:

  • 这是预期的限制,还是后台的技术复杂性?
  • 是否记录在某处?
  • 是特定于实现还是标准行为?

编辑:回答清楚,并在那里查看我的评论。这是一个简单的对象文字问题(非问题,而不是:),与Object.defineProperties()没有直接关系。

1 个答案:

答案 0 :(得分:4)

这个问题与Object.defineProperties()没什么关系。问题在于对象初始化表达式的方式 - "对象文字"是另一个术语 - 被评估。对象初始值设定项一个表达式,在进行评估之前,它初始化的对象并不存在。因此,在

Object.defineProperties(foo, {
    "one" : {value: 1, enumerable: true},
    "two" : {value: foo.one + 1, enumerable: true}
});

对象初始值设定项子表达式是

{
    "one" : {value: 1, enumerable: true},
    "two" : {value: foo.one + 1, enumerable: true}
}

必须在调用Object.defineProperties()之前对其进行评估。在评估时,foo没有名为" one&#34 ;;即使它确实如此,正在评估对象初始值设定项的值将是先前的值,而不是新值。

这就是对象初始化表达式的工作方式。不可能直接引用从表达式中初始化的对象。这意味着即使在这样的声明中:

var foo = {
    "one" : {value: 1, enumerable: true},
    "two" : {value: foo.one + 1, enumerable: true}
};

你仍然有同样的问题。