繁体   English   中英

初始化对象缺失成员的最优雅方式,同时创建对新成员的引用

[英]Most elegant way to initialise missing members of an object, whilst creating reference to new member

请需要最优雅的解决方案。 我们都处理可以在整个生命周期中逐步构建的对象。 传递对象引用是处理对象最有用的方法,因为变异会影响原始对象而不仅仅是副本。

例如:

const bigObject = fetchBigObjectFromStorage()
let myMem = bigObject.member || {}

如果member存在于bigObject ,则myMem获得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 个,并且行为可靠(好吧,几乎...... ifif进行几次测试可能会使其不漏水)。 但它和罪恶一样丑陋,而且为如此微不足道的事情编写了太多代码。 我们可以将像if语句这样的部分重构为一个小函数,使其成为通用成员初始化程序,以及其他一些方法。 我相信我们中的大多数人多年来都尝试过很多技术。 但是,从聚集的学习人群中,最优雅、最受青睐的解决方案是什么? 有什么巧妙的小技巧吗?

您可以使用条件运算符缩短if语句:

const myMem = bigObject.hasOwnProperty("member") 
  ? bigObject.member
  : (bigObject.member = {value: null});

如果真实性检查对您来说足够了,那么您可以使用短路逻辑运算符进一步简化:

const myMem = bigObject.member || (bigObject.member = {value: null});

最优雅的方法可能是 ES6 解构提供的默认初始化器,它隐式测试undefined

const { member: myMem = (bigObject.member = {value: null}) } = bigObject;
let myMem = bigObject.member = bigObject.member || {};
myMem.value = 30;
console.log(bigObject.member.value);  // outputs 30

我认为这可能是诀窍之一

怎么样

const bigObject = {...defaults, ...fetchBigObjectFromStorage()}

defaults类似于:

{member: {value: null} etc}

这样,您的对象始终具有所有预期字段。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM