2012-08-31 117 views
1

可能重複:
Dynamic object property name串聯訪問的對象屬性

我要動態地生成訪問對象的屬性。

如果我嘗試訪問mydata[i].val.name,我會得到somename

如果我嘗試像mydata[i] + bar[j](其中bar [j] ==='.val.name')它失敗。

我該如何動態創建這樣的東西?這樣我可以使用用戶生成的值訪問對象的任何屬性?


一些代碼:

如果我有一個對象我希望能夠通過它的屬性進行迭代,收集我感興趣的是那些理想的情況下,我想類似如下:

var processData = function (data, keys, values) { 
    var returnData = [], i, j, k; 
    var parsedData = JSON.parse(data); 
    var keys = keys || null; 
    var values = values || null; 
    var datalen = parsedData.length; 

    for (i = 0; i < datalen; i++) { 
     returnData[i] = {}; 
     for(j = 0; j< keys.length; j++){ 
      for(k = 0; k < values.length; k++){ 
       returnData[i][keys[j]] = parsedData[i] + values; 
      } 
     } 
    } 

    return returnData; 
}; 

,然後用它喜歡:

var keys = ["foo","bar"]; 
var values = [".val.name", ".val.date"]; 
processData(data, keys, values); 

但是,這並不工作,並在CONSOL e我看到foo="[object Object].val.name"而不是預期的foo="ACME Industries"

+0

你可以發佈你正在使用的對象的例子嗎?我也會小心命名對象和參數相同,它只是看起來容易混淆,可能會導致問題。 – elclanrs

+0

^^同意。這個'mydata [i] + bar [j]'連接任何這些值。 – elclanrs

+0

我已經更新了我的答案,以便在問題結束時使用查詢,並演示了它的工作原理。 –

回答

1

如果你要堅持你的構建標與它點的字符串,你必須推出自己的查找功能,像這樣的模式:

function descend(object, sub) { 
    var handle = object, 
     stack = sub.split('.'), 
     history = [], 
     peek; 

    while (handle[stack[0]]) { 
     if (peek) { 
      history.push(peek); 
     } 
     peek = stack.shift(); 
     handle = handle[peek]; 
    } 

    if (stack.length > 0) { 
     history.push(peek); 
     throw "Traversal error, could not descend to '" + stack.join('.') + "' from '" + history.join('.') + "'."; 
    } 

    return handle; 
} 

var x = { 
    a: { 
     b: { 
      c: 15 
     }, 
     d: 4 
    } 
}; 

console.log(descend(x, "a")); 
console.log(descend(x, "a.b")); 
console.log(descend(x, "a.b.c")); 
console.log(descend(x, "a.d")); 

function processData(data, keys, values) { 
    if (keys.length !== values.length) { 
     throw "Mismatched keys and value lookups"; 
    } 

    var i, 
     len = keys.length, 
     gathered = {}, 
     k, 
     scratch, 
     v; 

    for (i = 0; i < len; i += 1) { 
     k = descend(data, keys[i]); 
     scratch = values[i].split('.'); 
     scratch.shift(); 
     v = descend(k, scratch.join('.')); 
     gathered[keys[i]] = v; 
    } 

    return gathered; 
} 

var data = { 
    foo: { 
     val: { 
      name: "ACME Industries" 
     } 
    }, 
    bar: { 
     val: { 
      date: (new Date()) 
     } 
    } 
}; 
var keys = ["foo","bar"]; 
var values = [".val.name", ".val.date"]; 
processData(data, keys, values); 

請注意:這不會是近作爲沒有這種查找風格的編碼的表現。

+0

已添加:未經測試的processData()函數 –

+0

經過測試的processData()函數 –

+0

如果此類查找不是高性能的,那麼樣式是什麼? – Lothar

1

如果你嘗試:

new Object() + '.john.doe' 

它將串聯爲一個字符串,所以你會得到"[object Object].john.doe"

您應該創建一個可以處理動態屬性名稱的函數(並且有很多這樣的函數)。您也可能想將".foo.bar"語法作爲一個字符串(除非您計劃使用eval())並且僅使用數組來處理。

0

如果我理解正確的話,你需要使用

mydata[i]["val"]["name"] 

所以,我會使用這樣的:

var result =getItemByValuesPath(myData[i],values); 
alert(result); 

function getItemByValuesPath(item, values) 
{ 
    var result = item; 

    var vals = values.split("."); 
    for(var j=0; j<values.length; j++) 
    { 
     if(result==undefined) 
      { 
        return null; 
      } 
    result = result[values[j]]; 
    } 
}