如何在不使用eval的情况下访问定义为字符串的嵌套属性?

时间:2015-08-14 19:18:53

标签: javascript

我有一个可能有也可能没有嵌套对象和属性的对象,我想用字符串访问它们。这是一个例子......

var obj = {
    inside: {
        value: 10,
        furtherInside: {
            value: 100
        }
    }
    // may contain other objects, properties, etc.
};
function getObjProperty(str) {
    return eval("obj." + str);
}
getObjProperty("inside.value"); // returns 10
getObjProperty("inside.furtherInside.value"); // returns 100

...但我想要一个不使用eval的解决方案。 如何在不使用eval 的情况下完成?我正在寻找最佳/最佳/最快的解决方案。

4 个答案:

答案 0 :(得分:5)

这样的东西
find

此代码假定您的字符串始终有效,并且传递到function getObjectProperty(obj, str) { var props = str.split('.') var result = obj; for(var i = 0; i < props.length; i++) result = result[props[i]]; return result; } 的对象具有嵌套到您定位的级别的属性,但它避免getObjectProperty。您可以通过检查未定义来使其更加健壮,但这对您所需的内容来说可能过度。

使用您的示例测试代码:

eval

答案 1 :(得分:1)

您可以使用括号表示法:

var obj = {
    inside: {
        value: 10,
        furtherInside: {
            value: 100
        }
    }
    // may contain other objects, properties, etc.
};

alert(obj['inside']['furtherInside']['value']);

然后你甚至可以使用&#34;我的属性&#34;:

之类的字符串属性
var obj = {
   "my property": 10
};

obj["my property"];

修改

这是一种方法(使用括号表示法)来满足您的要求:

String.prototype.getVal = function(elem) {
    var segments = this.split('.');
    for (var i = 0; i < segments.length; i++) {
        elem = elem[segments[i]];
    } 
    return elem;
}

var obj = {
    inside: {
        value: 10,
        furtherInside: {
            value: 100
        }
    }
    // may contain other objects, properties, etc.
};
console.log("inside.furtherInside.value".getVal(obj));
console.log("inside.value".getVal(obj));

http://jsfiddle.net/luismartin/kphtqd54

由于此方法将getVal()分配给String原型,您可以在任何地方使用它,我认为实现非常简洁快速。我希望这种方法也有助于摆脱反对票:/

答案 2 :(得分:0)

这就是我提出的,使用一些递归...

function getObjProperty(obj, props) {
    if (typeof props === 'string') {
        if (props.indexOf('.') == -1) {
            return obj[props];
        } else {
            props = props.split('.');
        }
    }
    if (props.length == 1) {
        return obj[props[0]];
    } else if (props.length > 1) {
        var top = props.shift();
        return getObjProperty(obj[top], props);
    } else {
        return obj;
    }
}

http://jsfiddle.net/0em2f6k6/ ......但它不如简单的for循环快。 http://jsperf.com/0em2f6k6

答案 3 :(得分:0)

虽然不是vanilla JavaScript,但另一种可能性是使用lodash的_.get函数:https://lodash.com/docs#get

_.get(obj, "inside.furtherInside.value");

它基本上与@analytalica的解决方案相同,除了使用while循环(参见lodash code中的baseGet函数),但它也允许字符串或数组(使用toPath函数),并允许您包含默认值。