如何在Javascript中进行深度可选赋值?
How to perform deep optional assignment in Javascript?
假设我有一个名为 foo
的对象,我想执行以下操作:
foo.bar.baz.qwer.asdf = 5;
问题是bar
可能不存在,但如果存在,那么里面的baz
也可能不存在,等等
我以为我可以做这样的事情:
foo?.bar?.baz?.qwer?.asdf = 5
,可惜,这种链接似乎只适用于检索值,而不适用于设置值。
期望的行为是,如果 baz
之类的东西已经存在,则只访问该对象(并维护其现有成员),但如果 baz
不存在,则 属性 是即时创建的。
也就是说,假设只有 foo.bar
存在。那么经过上面的赋值操作,得到的对象就是:
foo {
bar: {
baz: {
qwer: {
asdf: 5
}
}
}
}
所以我的问题是:这可以用现有的语言语法结构来完成,还是必须创建一个辅助函数?如果是这样,这种函数是否有一个我可以搜索和参考的名称?
我写了这个:
function setProperty(obj, property, value) {
const properties = property.split('.');
const lastProperty = properties.pop();
for (let prop of properties) {
if (!obj[prop]) {
obj[prop] = {};
}
obj = obj[prop];
}
obj[lastProperty] = value;
}
const startObj = {'a': {}};
setProperty(startObj, 'a.b.c.d.e', 'e is the best letter');
console.log(startObj);
但是,如果其中一个中间属性存在但不是对象,则会出现意外行为。例如用起始对象 {a:{b:2}}
测试上面的函数
此外,请注意 obj
的含义会随着函数的处理而变化。起初,它表示基础对象,但它继续表示循环中的每个嵌套对象。
假设我有一个名为 foo
的对象,我想执行以下操作:
foo.bar.baz.qwer.asdf = 5;
问题是bar
可能不存在,但如果存在,那么里面的baz
也可能不存在,等等
我以为我可以做这样的事情:
foo?.bar?.baz?.qwer?.asdf = 5
,可惜,这种链接似乎只适用于检索值,而不适用于设置值。
期望的行为是,如果 baz
之类的东西已经存在,则只访问该对象(并维护其现有成员),但如果 baz
不存在,则 属性 是即时创建的。
也就是说,假设只有 foo.bar
存在。那么经过上面的赋值操作,得到的对象就是:
foo {
bar: {
baz: {
qwer: {
asdf: 5
}
}
}
}
所以我的问题是:这可以用现有的语言语法结构来完成,还是必须创建一个辅助函数?如果是这样,这种函数是否有一个我可以搜索和参考的名称?
我写了这个:
function setProperty(obj, property, value) {
const properties = property.split('.');
const lastProperty = properties.pop();
for (let prop of properties) {
if (!obj[prop]) {
obj[prop] = {};
}
obj = obj[prop];
}
obj[lastProperty] = value;
}
const startObj = {'a': {}};
setProperty(startObj, 'a.b.c.d.e', 'e is the best letter');
console.log(startObj);
但是,如果其中一个中间属性存在但不是对象,则会出现意外行为。例如用起始对象 {a:{b:2}}
此外,请注意 obj
的含义会随着函数的处理而变化。起初,它表示基础对象,但它继续表示循环中的每个嵌套对象。