3

当我尝试使用字符串访问全局数组索引的属性时遇到了问题。我有动态生成的字符串,看起来像这样:

var foo = "arr[0].prp[0].prp[1]"

数组中的索引及其深度是动态的,我只是提供了一个示例来说明它的外观。

现在的问题是当我尝试使用这个字符串来获取这样的属性时,它失败了:

foo.something, foo["something"],window[foo].somethingwindow[foo]["something"]

然而,我可以使用 eval() 让它工作,但我真的很想离开而不必使用它。

有人有什么建议或想法吗?

4

3 回答 3

1

使用eval可能不是一个好主意,所以我将提供一个替代解决方案。如果您提供了字符串的生成方式,则可以省去解析它并改写生成器的麻烦。

您生成了一个字符串,看起来像

var foo = "arr[0].prp[0].prp[1]";

如果你使用这样的RegExp/\[\d+\]|\..*?(?=[\.\[])/ig会发生什么?

var m = foo.match(/\[\d+\]|\..*?(?=[\.\[])|^.*?(?=[\.\[])/ig);
// ["arr", "[0]", ".prp", "[0]", ".prp", "[1]"]

只需要多一点解析

m = m.map(function (e) {
    if (e.charAt(0) === '.') return e.slice(1);
    else if (e.charAt(0) === '[') return e.slice(1, -1);
    else return e
});
// ["arr", "0", "prp", "0", "prp", "1"]

现在你可以循环它了

var o = window, i;
for (i = 0; i < m.length; ++i) {
    o = o[m[i]];
}
// o is now the result of window.arr[0].prp[0].prp[1]
于 2013-06-08T20:41:59.760 回答
1

*现场演示*

var part = {
    "arr": [
        {
            "prp": [
                {
                    "prp": [
                        "result"
                     ]
                }
            ]
        }
    ]
};
var foo = "arr[0].prp[0].prp[0]";

function getValue(obj, chain) {
    var keys = chain.split('\.'),
        iterable = [];
    for (var i = 0, len = keys.length; i < len; i++) {
        var parts = keys[i].split('[');
        parts[1] = parts[1].replace('\]', '');
        iterable.push(parts[0], parts[1]);
    }
    target = obj[iterable[0]];

    for (var j = 1, len = iterable.length; j < len; j++) {
        target = target[iterable[j]];
    };
    return target;
};
于 2013-06-08T20:47:53.523 回答
1

另一种方法:

    var obj = {
        arr: [{
            prp: [{
                prp: ['a', 'b', 'c']
            }]
        }]
    };
    var foo = "arr[0].prp[0].prp[1]";

    var path = foo.replace(/\]/g, "").replace(/\[/g, ".").split('.').reverse();
    var res = obj;
    while (path.length && res){
        var el = path.pop();
        res = res[el];
    }

    console.log(res);
于 2013-06-08T20:58:34.110 回答