2014-01-13 89 views
2

鑑於以下OBJ:入門嵌套OBJ值

var inputMapping = { 
nonNestedItem: "someItem here", 
sections: { 
    general: "Some general section information" 
} 
}; 

我通過傳遞串"nonNestedItem"或在巢式病例"sections.general"寫一個函數來get數據。我不得不使用eval我想知道是否有更好的方法來做到這一點。

這是我到目前爲止,它的工作原理好。但改善!

function getNode(name) { 
    var n = name.split("."); 

    if (n.length === 1) { 
    n = name[0]; 
    } else { 
    var isValid = true, 
     evalStr = 'inputMapping'; 

    for (var i=0;i<n.length;i++) { 
     evalStr += '["'+ n[i] +'"]'; 

     if (eval(evalStr) === undefined) { 
     isValid = false; 
     break; 
     } 
    } 

    if (isValid) { 
     // Do something like return the value 
    } 
    } 
} 

Linky to Jsbin

+1

這裏沒有JSON。不要將JavaScript對象與JSON混淆。 – Quentin

+0

[JavaScript對象:通過名稱作爲字符串訪問變量屬性]的可能重複(http://stackoverflow.com/questions/4255472/javascript-object-access-variable-property-by-name-as-string) – Quentin

+0

冷靜下來。確定它的一個js對象,我將刪除對'json'的所有引用。雖然有點挑剔。我不認爲這是一個愚蠢的問題。 –

回答

5

可以使用Array.prototype.reduce功能這樣

var accessString = "sections.general"; 

console.log(accessString.split(".").reduce(function(previous, current) { 
    return previous[current]; 
}, inputMapping)); 

輸出

Some general section information 

如果您的環境不支持reduce,您可以使用此遞歸版本

function getNestedItem(currentObject, listOfKeys) { 
    if (listOfKeys.length === 0 || !currentObject) { 
     return currentObject; 
    } 
    return getNestedItem(currentObject[listOfKeys[0]], listOfKeys.slice(1)); 
} 
console.log(getNestedItem(inputMapping, "sections.general".split("."))); 
+2

哇!巧妙使用'.reduce()'! –

+1

如果它不存在,你也可以在'.reduce()'中填充:https://github.com/es-shims/es5-shim –

2

這裏您不需要使用eval()。您只需使用[]即可從對象中獲取值。使用臨時對象來保存當前值,然後在每次需要下一個鍵時更新它。

function getNode(mapping, name) { 
    var n = name.split("."); 

    if (n.length === 1) { 
     return mapping[name]; 
    } else { 
     var tmp = mapping; 
     for (var i = 0; i < n.length; i++) { 
      tmp = tmp[n[i]]; 
     } 
     return tmp; 
    } 
}