说我有这样一个对象:
a : {
a1 : {
a2: true
}
}
我将所有路径保存在数组中:
[a1, a2]
如果我想为[“a1”] [“a2”]赋值,很容易:
a["a1"]["a2"] = true;
但是当我有这样的3级路径时:
[a1, a2, a3]
我必须手动编写如下代码:
a["a1"]["a2"]["a3"] = true;
有没有办法自动处理任何级别的路径,这样我就不必为每一个案例明确说明?
请注意,“a”可能非常复杂,因此我只想为此特定元素指定值而不触及其余元素。
答案 0 :(得分:5)
您可以使用如下路径迭代遍历对象:
function setDeepProperty(obj, path, value)
{
var curr = obj;
for (var depth = 0; depth < path.length - 1; depth++)
{
curr = curr[path[depth]];
}
curr[path[path.length - 1]] = value;
}
这假定路径有效。如有必要,请确保path[depth] in curr
。遍历的最后一步是在循环之外完成的,因为它将curr
设置为基本类型而不是引用数组(如我们所愿),这意味着它不会更改原始数据。然后,按照你的例子:
var arr = {a1: {a2: { a3: false }}};
setDeepProperty(arr, ["a1", "a2", "a3"], true);
请注意,路径中的节点是字符串。
答案 1 :(得分:3)
您可以通过多种方式访问这些属性:
使用循环:
var obj = {
a1 : {
a2: { a3: 'test' }
}
},
i = 0,
keyPath = ['a1', 'a2', 'a3'],
len = keyPath.length;
for (; i < len; i++) {
obj = obj[keyPath[i]];
}
console.log(obj);
使用eval
(我不建议这样做):
var obj = {
a1 : {
a2: { a3: 'test' }
}
};
var value = eval('obj.' + keyPath.join('.'));
console.log(value);
您可以使用相同的方法在特定关键路径设置属性:
function setProperty(obj, keyPath, value) {
var i = 0,
len = keyPath.length - 1;
for (; i < len; i++) {
obj = obj[keyPath[i]];
}
obj[keyPath[i]] = value;
}
答案 2 :(得分:1)
所有这些都是优雅的解决方案,我的2美分递归: -
var a = {
a1: {
a2: {
a3: false
}
}
};
var path = ['a1', 'a2', 'a3'];
var valueToSet = true;
setValue(0, a);
function setValue(level, ob) {
var prop = path[level];
if (!ob.hasOwnProperty(prop)) {
return;
}
if (level == (path.length - 1)) {
ob[prop] = valueToSet;
return;
}
return setValue(level + 1, ob[prop]);
}
console.log(a);
答案 3 :(得分:0)
您有两种可能性:
代码:
var a={
a1 : {
a2 : {
a3: false
}
}
};
var idx=["a1", "a2", "a3"];
function recReplace(o, i, v) {
var ii=i.shift();
if (i.length==0)
o[ii]=v;
else
o[ii]=recReplace(o[ii],i,v);
return o;
}
b=recReplace(a,idx,true); //or: a=recReplace(a,idx,true);
答案 4 :(得分:0)
当然,这是一个简单的循环:
var a = {a1:{a2:{}}};
var path = ["a1", "a2", "a3"];
for (var o=a, i=0; i<path.length-1; i++)
o = o[path[i]]; // notice that this will throw exception
// when the objects do not exist already
o[path[i]] = true;