Javascript: 通过将路径作为字符串传递给对象,从中获取深度值

可能的复制品:
使用字符串 key 访问嵌套的 JavaScript 对象

也许标题不够清楚,我只是不知道如何具体说明我在找什么,我的英语真的很差,对不起。

我试图创建一个函数来返回对象值,同时也可以很好地处理嵌套对象。例如:

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

我想通过向函数提供字符串“ foo.bar”来访问 objec.foo.bar 的值。

function(obj, path) {
// Path can be "foo.bar", or just "foo".
}

谢谢!

114670 次浏览

You'd want to split the string on the dot and then repeatedly index into the object, e.g. along the lines of:

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;
}

Live example

That works because you can access the property of an object in a couple of different ways: There's dotted syntax using a literal (obj.foo), and there's bracketed syntax using a string (obj["foo"]). In the latter case, the string can be the result of any expression, it doesn't have to be a string literal. In in all of the, rv is set to the same value:

rv = obj.foo.bar;
// Or
rv = obj.foo["bar"];
// Or
f = "foo";
rv = obj[f].bar;
// Or
s = "b";
rv = obj.foo[s + "ar"];

something like:

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

Consider this:

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'))

This works correctly:

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;
};

Here is the proof / demo: jsfiddle.net/tadeck/5Pt2q/13/

EDIT: I have removed redundant variables, shortened the code.

You mean something like this ? It is a recursive version

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

See http://jsfiddle.net/kExSr/