向对象添加多个属性时,使用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()没有直接关系。
答案 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}
};
你仍然有同样的问题。