使用字符串检索对象的值

retrieving the value of object using strings

本文关键字:对象 检索 字符串      更新时间:2023-09-26

我在这里的情况下,我必须只与字符串的工作,因为我也必须从字符串检索对象的值,简而言之:

从对象中检索值,我们写:

someObject.property1.name // for say 

,但在我的情况下,我想从一个对象中检索值使用字符串,即

'someObject.property1.name' // for say

因为我不是那么自信,我可以做到这一点,所以我更喜欢在互联网上搜索,我得到的最合适的解决方案是

# 1

 Object.byString = function(o, s) {
    s = s.replace(/'[('w+)']/g, '.$1'); // convert indexes to properties
    s = s.replace(/^'./, '');           // strip a leading dot
    var a = s.split('.');
    while (a.length) {
        var n = a.shift();
        if (n in o) {
            o = o[n];
        } else {
            return;
        }
    }
    return o;
}
从这里

# 2

var deep_value = function(obj, path){
    for (var i=0, path=path.split('.'), len=path.length; i<len; i++){
        obj = obj[path[i]];
    };
    return obj;
};
从这里

,但正如我所说,它们是最合适的例子,因为它们都有一个额外的参数,即obj, O等等…这给我带来了麻烦,所以我试图在搜索2中改进上面的代码,因为它很紧凑,但这导致了失败。代码是:

    var obj = {
      foo: { bar: 'baz' }
    };
    var deep_value = function(path){
        var obj = path.split('.');
        obj = obj[0];
        for (var i=0, path=path.split('.'), len=path.length; i<len; i++){
            obj = obj[path[i+1]];
        };
        return obj;
    };
alert(deep_value('obj.foo.bar'));  

(我编辑他的代码只是为了一个实验)。上面的代码不需要obj,这是一个完美的代码-如果它工作-没有看到任何错误,那么为什么这段代码不工作,什么是正确的代码?

JSFIDDLE

thanks in advance

你的#3选项有几个问题:

首先obj = obj[0];会有obj === "obj",这对你一点帮助都没有。你需要获取window["obj"]来获取顶层对象。

其次,您遍历for循环的次数太多,并且超出了path数组的末尾。

如果obj在顶级范围内,在这两个领域进行更改将使其工作:

var obj = {
  foo: { bar: 'baz' }
};
var deep_value = function(path, baseObj){
    baseObj = baseObj || window;
    var obj = path.split('.');
    obj = baseObj[obj[0]];
    for (var i=1, path=path.split('.'), len=path.length; i<len; i++){
        obj = obj[path[i]];
    };
    return obj;
};
alert(deep_value('obj.foo.bar'));  

工作演示:http://jsfiddle.net/jfriend00/jGb5p/


下面是一个简洁的版本:

var obj = {
    foo: { bar: 'baz' }
};
var deep_value = function(path, baseObj){
    baseObj = baseObj || window;
    var pieces = path.split('.');
    // get root level object
    var obj = baseObj[pieces[0]];
    for (var i = 1, len = pieces.length; i < len; i++){
        obj = obj[pieces[i]];
    }
    return obj;
};
console.log(deep_value('obj.foo.bar'));  

工作演示:http://jsfiddle.net/jfriend00/7J4Jb/

这可以用reduce:

来简洁地表达
function eval_dotted_path(path) {
  return path.split('.').reduce(function(value, segment) {
    return value && value[segment];
  }, window);
}

这将路径分割为点上的"段",然后调用reduce在这些段上"循环",在每次迭代中找到对象内的下一个值。第一个片段在全局命名空间中,也就是"window"。

value && value[segment]确保如果在任何时刻当前值为null/undefined(因为segment属性不存在),则返回undefined/null。

如果您希望查找从已知对象开始的虚线路径所指示的值,则可以将其调整为

function eval_dotted_path_from_object(object, path) {
  return path.split('.').reduce(function(value, segment) {
    return value && value[segment];
  }, object);
}

之后可以将初始函数重新定义为

function eval_dotted_path(path) {
  return eval_dotted_path_from_object(window, path);
}

如果你在一个没有Array.prototype.reduce的旧环境中,考虑使用下划线的_.reduce,或者一个polyfill;