This question实现了与我正在努力做的相反的事情。基本上,我有这个对象:
var a = {
b: {
c: 'Foo'
}
}
我需要做的是设置给定字符串'b.c'的c的值。不幸的是,我不能这样做:
a['b.c'] = 'Bar'
据我所知,上面的问题并没有让我接近,因为它只是复制了对象属性的值,因此可以读取它们。但是,它无法帮助我设置对象属性的值。这是我到目前为止所做的:
var key = 'b.c'.split('.');
for (var i = 0; i < key.length; i++) {
// do something
}
答案 0 :(得分:3)
这是一种功能性的方式,这是你需要的吗?它不使用特定的a[string]
语法,而是一个可以传递对象字符串和值来设置的函数:
var obj = { foo: { bar: { lol: { lulz: 69 } } } };
function setProp(obj, prop, value) {
var props = prop.split('.');
return [obj].concat(props).reduce(function(a,b,i) {
return i == props.length ? a[b] = value : a[b];
});
}
setProp(obj, 'foo.bar.lol.lulz', 'hello world');
console.log(obj.foo.bar.lol.lulz); //=> "hello world"
答案 1 :(得分:1)
你必须截取循环的最后一次迭代,并从那里分配而不是重新定义你的临时变量。
我根据您关联的问题调整了答案,将值2
分配给a.b.c
:
var a = {
"b" : {
"c" : 1
}
}
var n = "b.c".split(".");
var x = a;
for(var i = 0; i < n.length; i++){
if(i == n.length-1) {
x[n[i]] = 2;
} else {
x = x[n[i]];
}
}
这就是@Ian在他的jsfiddle中所做的事情。一个if
的Intead,他循环一步,然后在循环后处理赋值。
答案 2 :(得分:0)
为了记录,我最终想出了另一种方法:
function setProperty(obj, props, val) {
if (obj[props[0]] instanceof Object) {
setProperty(obj[props[0]], props.slice(1, props.length), val);
return;
}
obj[props[0]] = val;
}
这样称呼:
a = {
b: {
c: 'Foo'
}
};
var whatever = 'b.c';
var props = whatever.split('.');
setProperty(a, props, 'Bar');