2014-01-22 212 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:我錯過了「設置」部分。更新了可處理兩者的單一功能。 –