动态深度选择JavaScript对象 [英] Dynamic deep selection for a JavaScript object
问题描述
使用单个属性这很容易:
With a single property this is fairly easy:
var jsonobj = {
"test": "ok"
}
var propname = "test";
// Will alert "ok"
alert(jsonobj[propname]);
但我想要做的是使用嵌套属性:
But what I want to do is use a nested property:
var jsonobj = {
"test": {
"test2": "ok"
}
}
var propname = "test.test2";
// Alerts undefined
alert(jsonobj[propname]);
有没有办法选择嵌套的动态属性?
我知道我可以做jsonobj.test.test2,但问题是propname可以改为1,2或3级深的属性。 (例如test,test.test2,...)
Is there any way of selecting a nested "dynamic" property? I know I can do jsonobj.test.test2, but the problem is that propname can change to a property that goes 1,2 or 3 levels deep. (e.g test, test.test2, ...)
推荐答案
function resolve(cur, ns) {
var undef;
ns = ns.split('.');
while (cur && ns[0])
cur = cur[ns.shift()] || undef;
return cur;
}
例如。
// 1:
resolve({
foo: { bar: 123 }
}, 'foo.bar'); // => 123
// 2:
var complex = {
a: {
b: [
document.createElement('div')
]
}
};
resolve(complex, 'a.b.0.nodeName'); // => DIV
使用此功能的好处是,如果您尝试访问某些内容,它不会引发错误不存在 - 它将优雅地返回 undefined
。
The benefit in using this is that it won't throw an error if you try accessing something that doesn't exist -- it'll gracefully return undefined
.
编辑:
在评论中,Andy提到这不会引发人们可能期望的错误。我同意获得 undefined
有点通用,没有办法判断你的价值是否真的得到了解决。所以,为了解决这个问题,试试这个:
In the comment, Andy mentioned that this doesn't throw errors where one might expect it to. I agree that getting undefined
is a little bit generic and there is no way to tell whether your value was really resolved. So, to remedy that, try this:
var resolve = (function(){
var UNRESOLVED = resolve.UNRESOLVED = {};
return resolve;
function resolve(cur, ns) {
var undef;
ns = ns.split('.');
while (cur && ns[0])
cur = cur[ns.shift()] || undef;
if (cur === undef || ns[0]) {
return UNRESOLVED;
}
return cur;
}
}());
它将返回一个UNRESOLVED对象,可以这样检查:
It'll return an UNRESOLVED object that can be checked like so:
var result = resolve(someObject, 'a.b.c');
if (result === resolve.UNRESOLVED) {...}
它并不完美,但它是(IMO)确定未解析的命名空间而不必抛出错误的最佳方法。如果你想要错误,那么请继续:
It's not perfect, but it is (IMO) the best way to determine an unresolved namespace without having to throw errors. If you want errors, then just go ahead with:
someObject.a.b.c; //...
这篇关于动态深度选择JavaScript对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!