【发布时间】:2018-03-07 19:39:07
【问题描述】:
请提供最优雅的解决方案。我们都处理可以在其整个生命周期中增量构建的对象。传递对象引用是处理对象最有用的方法,因为突变会影响原始对象而不仅仅是副本。
例如:
const bigObject = fetchBigObjectFromStorage()
let myMem = bigObject.member || {}
如果member 存在于bigObject 中,myMem 将获得对其的引用。如果不是,它只会接收对新空对象的引用。所以这会产生不可预知的结果:
myMem.value = 30
没有错误。 myMem.value 现在是 30。但是值最终达到了我们真正想要的位置吗?
console.log(bigObject.member.value)
这要么显示 30,要么给出 TypeError,因为 bigObject.member 未定义,取决于 bigObject.member 是否已经存在。
为避免错误,我们可以将新值放回bigObject,每次都将其放回那里,因此我们需要显式分配它:
bigObject.member = myMem
这是乱七八糟的。
所以我们可以预先排除bigObject.member 不存在的可能性,对其进行测试,并在我们开始尝试传递对它的引用之前插入它,甚至使用空值初始化所需的成员。所以我们有这个代码:
const bigObject = fetchBigObjectFromStorage()
if (!bigObject.hasOwnProperty("member")) bigObject.member = {value: null}
let myMem = bigObject.member
myMem.value = 30
console.log(bigObject.member.value)
...我们每次都不会出现错误,显示 30 个并且行为可靠(嗯,几乎...在if 中进行更多测试可能会使其无懈可击)。但这就像罪恶一样丑陋,对于如此微不足道的事情来说代码太多了。我们可以像 if 语句那样将它的一部分重构为一个小函数,使其成为通用成员初始化器,以及其他一些方法。我敢肯定,多年来,我们大多数人都尝试了很多技术。但是,从聚集的博学人群中,最优雅、最受青睐的解决方案是什么?有什么巧妙的小技巧吗?
【问题讨论】:
标签: javascript ecmascript-6 javascript-objects lazy-initialization