Javascript:通过将路径作为字符串传递给它来从对象获取深层值

7el*_*ant 59 javascript syntax path

可能重复:
使用字符串键访问嵌套的JavaScript对象

也许标题不够明确,我只是不知道如何指定我正在寻找的东西,我的英语真的很糟糕,抱歉.

我正在尝试创建返回对象值的函数,但也可以使用嵌套对象.例如:

var obj = {
  foo: { bar: 'baz' }
};
Run Code Online (Sandbox Code Playgroud)

我想通过将字符串"foo.bar"提供给函数来访问obj.foo.bar的值.

function(obj, path) {
  // Path can be "foo.bar", or just "foo".
}
Run Code Online (Sandbox Code Playgroud)

谢谢!

Tad*_*eck 78

这工作正常:

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;
};
Run Code Online (Sandbox Code Playgroud)

这是证明/演示:jsfiddle.net/tadeck/5Pt2q/13/

编辑:我删除了冗余变量,缩短了代码.

  • @SteveBlack怎么样?它支持更受限制的语法,并且没有错误检查以尝试解析不存在的密钥. (4认同)
  • 改变参数是不好的做法。 (3认同)
  • 美丽。比重复的http://stackoverflow.com/questions/6491463/accessing-nested-javascript-objects-with-string-key中的任何内容都要好 (2认同)
  • 与ES6相同:`const deep_value =(o,p)=&gt; p.split('。')。reduce((a,v)=&gt; a [v],o);` (2认同)

qia*_*iao 41

考虑一下:

var obj = {
  foo: { bar: 'baz' }
};

function deepFind(obj, path) {
  var paths = path.split('.')
    , current = obj
    , i;

  for (i = 0; i < paths.length; ++i) {
    if (current[paths[i]] == undefined) {
      return undefined;
    } else {
      current = current[paths[i]];
    }
  }
  return current;
}

console.log(deepFind(obj, 'foo.bar'))
Run Code Online (Sandbox Code Playgroud)

  • @ 7elephant和qiao:如果路径的任何部分评估"null",则失败(抛出错误).根据您的观点,这可能是一个功能或错误.:-) (6认同)
  • 如何处理对象内部的数组? (2认同)

fyr*_*fyr 8

你的意思是这样的?这是一个递归版本

function recLookup(obj, path) {
    parts = path.split(".");
    if (parts.length==1){
        return obj[parts[0]];
    }
    return recLookup(obj[parts[0]], parts.slice(1).join("."));
}
Run Code Online (Sandbox Code Playgroud)

http://jsfiddle.net/kExSr/

  • 这看起来不太快。不应再次 join() 路径,只需检查路径是字符串还是数组 (2认同)

T.J*_*der 6

您想在点上拆分字符串,然后重复索引到对象中,例如沿着以下几行:

function goDeep(obj, path) {
    var parts = path.split('.'),
        rv,
        index;
    for (rv = obj, index = 0; rv && index < parts.length; ++index) {
        rv = rv[parts[index]];
    }
    return rv;
}
Run Code Online (Sandbox Code Playgroud)

活生生的例子

这是有效的,因为您可以通过几种不同的方式访问对象的属性:使用文字 ( obj.foo)的点语法,使用字符串 ( obj["foo"])的括号语法。在后一种情况下,字符串可以是任何表达式的结果,它不必是字符串文字。在所有的中,rv设置为相同的值:

rv = obj.foo.bar;
// Or
rv = obj.foo["bar"];
// Or
f = "foo";
rv = obj[f].bar;
// Or
s = "b";
rv = obj.foo[s + "ar"];
Run Code Online (Sandbox Code Playgroud)


Dan*_* D. 6

就像是:

function(obj, path) {
  var current=obj; 
  path.split('.').forEach(function(p){ current = current[p]; }); 
  return current;
}
Run Code Online (Sandbox Code Playgroud)

  • 另一种没有变异的方法:`const lens =(obj,path)=> path.split(".").reduce((o,key)=> o && o [key]?o [key]:null,obj) ;` (5认同)
  • @YuriyGorbylov 几乎完美,添加了一个 typeof 来允许虚假值(`0`等):`(obj, path) =&gt; path.split(".").reduce((o, key) =&gt; o &amp;&amp; typeof o [key] !== '未定义' ? o[key] : 未定义, obj)` (3认同)