代码之家  ›  专栏  ›  技术社区  ›  Zachary Scott

如何将此JavaScript字符串“myArray[0].myPrice”转换为对myPrice的引用?

  •  1
  • Zachary Scott  · 技术社区  · 15 年前

    如果我有一串 "myArray[0].myPrice" ,我如何将此提交给 myPrice ?

    这是代码上下文:

    binding.value = convert(binding.data[binding.field], 
                            binding.converter, binding.data, elem); 
    

    binding.field 是包含“myArray[0].myPrice”的内容。

    binding.data 具有对具有myArray数组属性的分层对象的引用,并且第一个元素是具有myPrice属性的对象。

    编辑:根据答案,这是有效的:

    binding.value = convert(eval('(binding.data.' + binding.field + ')'), 
                  binding.converter, binding.data, elem);
    

    像这样使用eval好吗?我以为eval会在新的JavaScript中消失?

    5 回复  |  直到 15 年前
        1
  •  2
  •   glebm    15 年前

    你可以用 eval ,但有一个更好的解决方案:

    // The following code results in the same as that scary eval(...)
    
    var data = binding.data,
        chain = binding.field.split(/[\.\[\]]+/);
    
    for (var i = 0; data[chain[i]]; i++) {
        data = data[chain[i]];      
    }
    
    // Embrace JavaScript Awesomeness!
    

    我在这里所做的事情的细目:

    在JS中,任何属性都可以称为 object[propertyName] .

    包括数组,即。 a[3] a['3'] .

    因此,我们使用以下字符之一拆分字符串: . , [ , ] . 这个 + 是不是因为没有它 a[3].b[3] 这个 ]. 会给你空的 弦。

    我们最后可能会得到一个空字符串,但这不是问题,因为 "" 就像 false 在JS。

    您可以进一步过滤掉所有无效的变量名,在javascript中,这是一个不符合 [a-zA-Z_$][0-9a-zA-Z_$]* . 但我不太清楚为什么会这样做。。。

        2
  •  1
  •   mway    15 年前

    好吧,它不太漂亮,但它没有用 eval :

    var str = 'myArray[0].myPrice';
    var parts = str.split(/[\[\].]+/);
    doSomething(window[parts[0]][parts[1]][parts[2]]);
    

    哪里 window[parts[0]][parts[1]][parts[2]] 是实际的参考。不知道为什么会有字符串版本 一个被载入记忆。

        3
  •  0
  •   icyrock.com    15 年前

    根据当前上下文,这可能会起作用:

    eval("myArray[0].myPrice")
    
        4
  •  0
  •   Steven de Salas Alexander Bollaert    15 年前

    尝试

    var a = eval("myArray[0].myPrice".split('.')[1]);
    

    但是,这在运行它的上下文中可能不起作用,因为 myPrice 指的是 window.myPrice 我怀疑这会被定义为什么。

    你最好的办法就是定义 myArray 在可以从任何地方访问的范围内(例如 window.AppNS.Data.myArray )然后使用 eval() 函数来访问此。

    var a = eval("window.AppNS.Data." + "myArray[0].myPrice") 
    alert(a) // the contents of myPrice are revealed
    
        5
  •  0
  •   Mic    15 年前

    这里有一些类似于我们在模板引擎中使用的逻辑 pure.js

    var obj = {
        myArr:[
            {price:15}
        ],
        anObj:{
            prop:'ABC'
        }
    };
    function getRef(o, path){
        var props = path.split(/\./),
            prop,
            isArr = /([^\[]+)(\[(\d+)\])*/,
            i = 0, ii = props.length;
        while(i < ii){
            prop = props[i].match(isArr);
            o = o[prop[1]];
            if(prop[2]){
                o = o[+prop[3]];
            }
            i++;
        }
        return o;
    }
    console.log(getRef(obj, 'myArr[0].price')); // --> 15
    console.log(getRef(obj, 'anObj.prop')); // --> ABC