2014-01-22 215 views
4

说我有一个这样的对象(简体):访问嵌套的对象

var options = { 
    boxes: { 
     size: { 
      x: 15, 
      y: 18 
     }, 
    shadow: { 
     [...] 
    } 
}; 

我有名字的数组:

var names = ['boxes', 'size', 'x']; 

什么是一个简单的方法根据数组获取/设置对象内的值,在本例中它将是:

options.boxes.size.x = somevalue; 

任何想法?

回答

4

有没有简单的,内置的方法来做到这一点。你必须写自己的方法:

function getPath(obj, props) { 
    for(var i = 0; i < props.length; i++) { 
     if (props[i] in obj) { 
      obj = obj[props[i]]; 
     } else { 
      return; // not found 
     } 
    } 

    return obj; 
} 

function setPath(obj, value, props) { 
    for(var i = 0; i < props.length - 1; i++) { 
     if (props[i] in obj) { 
      obj = obj[props[i]]; 
     } else { 
      return; // not found 
     } 
    } 

    obj[props[i]] = value; 
} 

alert(getPath(options, names)); // 15 
setPath(options, 25, names); 
alert(getPath(options, names)); // 25 
+0

感谢,这就像一个魅力! –

4

只需使用一个循环,遍历该names并抓住当前的名字下一嵌套对象。假的值或数组的末尾应该停止循环。

var obj = options; 
var i = 0; 

while (obj && i < names.length) 
    obj = obj[names[i++]]; 

或者干脆用.reduce()

names.reduce(function(obj, name) { 
    return obj && obj[name]; 
}, options); 

当然,您也可以命名,如果你喜欢重复使用的功能。

function toPropertyIn(obj, name) { 
    return obj && obj[name]; 
} 

names.reduce(toPropertyIn, options); 

要进行的getter/setter:

function nestedProp(obj, names, value) { 
    if (arguments.length > 1) 
     var setProp = names.pop(); 

    var res = names.reduce(function(obj, name) { 
     return obj && obj[name]; 
    }, options); 

    if (res && setProp !== undefined) 
     res[setProp] = value; 
    else 
     return res; 
} 


nestedProp(options, names, "foo"); // to set 

var val = nestedProp(options, names); // to get 
+1

第二个选项看起来很有趣,我会检查出来。谢谢! –

+0

@LarsEbert:我错过了“设置”部分。更新了可处理两者的单一功能。 –