0

Eval は一般的に悪い考えと見なされているようです。

ネストされたオブジェクトの評価に対するエレガントな解決策はありますか?

だから私の評価は

eval( "$scope" + lookup_string) 

Javascript オブジェクトは連想配列のように見えるので、試してみました

$scope[lookup_string] 

ネストされたオブジェクトに到達するまで、これはうまくいきました。

したがって、文字列にドットが含まれている場合、たとえば

lookup_string = "object1.object2.object3"

これは評価として機能します。ただし、3 つのネストされたルックアップとしてではなく、文字列を 1 つとして扱うため、associative_array ルックアップとしてではありません。

これで、文字列を分割して各部分を検索できることがわかりましたが、これはかなりの作業のようです (文字列を評価する場合と比較して)。

これに代わるクリーンでエレガントな代替手段はありますか?

4

2 に答える 2

3

通常、この問題には単純な while ループで十分です。

function nameSpace(obj, path) {
  var property, 
      path = path.split('.');
  while (property = path.shift()) {
    if (typeof obj[property] === 'undefined')
      return undefined;
    obj = obj[property]
  }
  return obj
}

アップデート

バニラを使いたいだけで、開発している環境がECMA-5をサポートしていると確信している場合は、次のようなことができます

function namespace(object, path) {
   var result = path.split('.').reduce(function (value, index) {
        return value[index]
    }, object)
   return result;
}
console.log(namespace(obj, 'a.b.value'))

reduceネイティブに実装されていない場合は、lodash などのライブラリを使用して追加することもできます。

于 2013-09-02T12:13:20.317 に答える
1

これは配列アイテムで動作します:

var oTest = {
    "mypc": {
        "cpu": {
            "cores": 1,
                "manufacturer": "",
                "model": "",
                "speed": 0
        },
            "group": "",
            "hdds": [{
            "capacitygb": 0,
                "driveletter": "c",
                "hddid": "a18822e92ff6e14cbc905bf4df13f8d3",
                "manufacturer": "",
                "port": 0,
                "type": ""
        }]
    }
};


var getProperty = function (obj, path) {
    return path.split(/(\[|\]|\.)/).reduce(function (x, y) {
        return ('[].'.indexOf(y) > -1) ? x : (x === Object(x) && y in x) ? x[y] : undefined;
    }, obj)
}

console.log(oTest.mypc.hdds[0].hddid)
console.log( 'ok: '+ getProperty(oTest, 'mypc.hdds[0].hddid')) 
console.log( 'undefined path: '+ getProperty(oTest, 'mypc.hdds[10].hddid')) 

于 2015-10-24T05:53:05.313 に答える