我有嵌套对象,例如:
var a = {b: {c: {d: 1}}};
和动态键:
var field = "b.c.d"
我需要通过密钥a
更改对象b.c.d
的值。对象和密钥的嵌套级别可以变化。唯一对我有用的是:
eval("a."+field+"=2"); -> it means a.b.c.d = 2;
但它很难看。有没有更好的办法?
您可以尝试使用递归函数
var a = {b: {c: {d: 1}}};
var field = "b.c.d";
var value = 2;
function updateObject(obj, key, val){
if(obj) {
if(key.includes(".")) {
var keys = key.split(".");
updateObject(obj[keys.shift()], keys.join("."), val);
} else if (obj.hasOwnProperty(key)) obj[key] = val;
}
}
updateObject(a, field, value);
console.log(a);
您只需使用递归函数来更新值:
var a = {b: {c: {d: 1}}};
function updateValue(obj, path,value){
if(typeof path == "string")
path = path.split(".");
if(path.length == 1)
obj[path[0]] = value;
else
updateValue(obj[path[0]], path.slice(1), value);
}
updateValue(a, "b.c.d", 2);
console.log(a);
这是另一种解决方案,如果您必须多次使用相同的路径并想要创建一个可用于设置值的函数:
var a = {b: {c: {d: 1}}};
function createSetter(path) {
return path.split(".")
.reverse()
.reduce((setter, key) =>
(setter
? (o,value) => setter(o[key],value)
: (o,value) => o[key]=value
), null)
}
var myBCDSetter = createSetter("b.c.d")
myBCDSetter(a,2)
console.log(a)
myBCDSetter(a,3)
console.log(a)
你可以使用lodash _.set(object, path, value)
。在你的情况下_.set(a, "b.c.d", 2)
请参阅docs here
您可以使用Function构造函数,它也适用于数组:
Object.prototype.modify = function (path,value){
let a = Function("object","path","value","object"+path+"=value");
a(this,path,value)
}
var a = {b: {c: {d: 1}}};
var b = {b: {c: {d: [1,[10,20,30],3,4,5]}}};
a.modify(".b.c.d", 3)//<-- change value
b.modify(".b.c.d[1][0]", "new Value")//<-- change value
console.log(a)
console.log(b.b.c)