假设我有一个这样的字典(这只是示例数据(:
obj = {
name: 'John',
properties: {
age: 42,
address: 'somewhere'
}
}
如果我想修改由变量指定的任何深度的值,该怎么办?
对于深度1,它将是直接的:
obj[what_to_modify] = new_value
但是对于深度>1.
what_to_modify="properties.age"
obj[what_to_modify.split('.')] = new_value
// I KNOW, THIS DOESN'T WORK, IT JUST
// ILLUSTRATES WHAT I WANT TO ACHIEVE
我的解决方案是这样做:
let levels = what_to_modify.split('.')
let it = obj
for(let k=0; k < levels.length; k++){
let key = levels[k]
if(k == levels.length -1){
it[key] = new_value
}else{
it = it[key]
}
}
这已经奏效了,但我想知道:有没有一种不那么混乱的方法
要明确的是,我不想只读取值,我想修改,所以在JavaScript中通过字符串路径和Access属性访问嵌套的JavaScript对象和数组?不要解决我的问题
重要
接受的答案使用lodash,但实际上我不应该在我的项目中包含新的依赖项,所以如果香草JS有其他方法,我会将接受的答案更改为。
您可以使用lodash。_.set
按路径设置值,_.get
按路径返回值。_.toPath
将字符串转换为路径数组。
const obj = {
name: 'John',
properties: {
age: 42,
address: 'somewhere'
}
};
const propertiesAgePath = _.toPath('properties.age');
console.log(_.get(obj, propertiesAgePath));
_.set(obj, propertiesAgePath, 43);
console.log(_.get(obj, propertiesAgePath));
_.set(obj, _.toPath('properties.address'), 'new address');
console.log(obj);
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
您也可以小心地使用eval来实现这一点。
let new_value = 9
obj = {
name: 'John',
properties: {
age: 42,
address: 'somewhere'
}
}
what_to_modify="properties.age"
eval("obj."+what_to_modify+"= new_value")
console.log(obj)