2016-08-30 126 views
0

我想從映射到屬性位置的數組中動態查找對象屬性。使用對象名稱和特殊名稱數組獲取對象屬性

Var objectA = { a:{b:1} }; 
Var Names = ['objectA','a','b']; 

豐和可以通過我上循環陣列名稱得到的b值?

+1

有一個類似的問題算法[這裏](http://stackoverflow.com/a/6491621/5743988)。 – 4castle

+0

爲什麼你覺得有必要這樣做?這對我來說似乎是一個XY問題。 – zzzzBov

+0

@zzzBov我hv商店singelron類,我希望其他類能夠監聽它的數據的specicifc分支上發生的變化,所以我覺得最好將地圖傳遞給prorerty我需要聽,所以bthat商店發出更新事件發生變化時。 – Zalaboza

回答

2

假設objectA被在全球範圍內可用(window.objectA),你可以做這樣的事情:

names.reduce(function (memo, value) { 
    return memo[value]; 
}, window) 

對於任何其他「非全局」變量,你可以創建一個getter函數,它的變量和路徑(數組就像你names,但沒有第一個值)作爲參數:

function nestedValue(obj, path) { 
    return path.reduce(function (memo, value) { 
     return memo[value]; 
    }, obj); 
} 

順便說一句,請注意Array.prototype.reduce()是ES2015的功能,因此,如果您需要與舊的瀏覽器兼容,你將不得不使用for循環的一些變化這個任務。

您也可以查看lodash.get獲取更復雜的解決方案(如果您願意將其包含在您的項目中)。

0

要做到這一點沒有eval需要你存儲ObjectA作爲另一個對象的屬性,你可以使用數組鍵進行迭代。 eval將在這種情況下工作,但:

objectA = { a: { b: 1 }} 
 
names = ['objectA', 'a', 'b'] 
 
alert(eval(names.join('.')))

1

你可以使用eval:eval(Names.join('.'))

可與nodejs使用沙盒裏面:

const util = require('util'); 
const vm = require('vm'); 

const objectA = { a: { b: 1 }}; 
const Names = ['objectA', 'a', 'b']; 

const sandbox = { objectA: objectA, Names: Names }; 
vm.createContext(sandbox); 

for (var i = 0; i < 10; ++i) { 
    vm.runInContext("var result = eval(Names.join('.'))", sandbox); 
} 
console.log(util.inspect(sandbox)); 

/* { 
    objectA: { a: { b: 1 } }, 
    Names: [ 'objectA', 'a', 'b' ], 
    result: 1 
    } 
*/ 
+0

創建一個沙盒並使用''eval''似乎是一個巨大的矯枉過正和浪費CPU時間。 – mdziekon