Object.defineProperties() 中的自引用

Self references in Object.defineProperties()

向一个对象添加多个属性时,使用 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 }

现在很明显,第二种解决方案总是有效的。但是,有人会假设第一个 也可以 工作,因为它 看起来 像另一个 shorthand 和 建议 属性的顺序处理。

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

所以问题是:

编辑:回答清楚,并在那里看到我的评论。这是一个简单的对象字面量问题(不是问题,而是 :),与 Object.defineProperties().

没有直接关系

这个问题与 Object.defineProperties() 并没有太大关系。问题在于对象初始值设定项表达式("object literals" 是另一个术语)的计算方式。一个对象初始值设定项 一个表达式,并且在它被求值之前,它正在初始化的对象并不真正存在。因此,在

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" 的 属性;即使是这样,正在评估对象初始值设定项时的值也将是先前的值,而不是新值。

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

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

你还有同样的问题。