JavaScript对象的动态深度选择
对于单个属性,这相当容易:JavaScript对象的动态深度选择,javascript,object,properties,Javascript,Object,Properties,对于单个属性,这相当容易: var jsonobj = { "test": "ok" } var propname = "test"; // Will alert "ok" alert(jsonobj[propname]); 但我要做的是使用嵌套属性: var jsonobj = { "test": { "test2": "ok" } } var propname = "test.test2"; // Alerts undefined alert(j
var jsonobj = {
"test": "ok"
}
var propname = "test";
// Will alert "ok"
alert(jsonobj[propname]);
但我要做的是使用嵌套属性:
var jsonobj = {
"test": {
"test2": "ok"
}
}
var propname = "test.test2";
// Alerts undefined
alert(jsonobj[propname]);
有没有办法选择嵌套的“动态”属性?
我知道我可以做jsonobj.test.test2,但问题是propname可以更改为深度为1、2或3级的属性。(例如test,test.test2,…)这是可行的,但它使用的是
eval
,所以我不建议使用它:
var jsonobj = {
"test": {
"test2": "ok"
}
}
var propname = "test.test2";
alert(eval("jsonobj." + propname));
在这里试试:您可以编写一个小函数来拆分字符串,然后依次访问每个片段。例如:
function getProperty(propname, object)
{
var props = propname.split('.');
var obj = object;
for (var i=0; i<props.length; i++)
{
obj = obj[props[i]];
}
return obj;
}
函数getProperty(propname,object)
{
var props=propname.split('.');
var obj=对象;
对于(var i=0;i
例如
使用它的好处是,如果您尝试访问不存在的东西,它不会抛出错误——它将优雅地返回未定义的
编辑:
在评论中,Andy提到,这不会在人们可能期望的情况下引发错误。我同意,获取未定义的
有点通用,无法判断您的值是否真的得到了解决。因此,要纠正这一点,请尝试以下方法:
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;
}
}());
它将返回一个未解析的对象,可以这样检查:
var result = resolve(someObject, 'a.b.c');
if (result === resolve.UNRESOLVED) {...}
它并不完美,但它是(IMO)确定未解析命名空间而不必抛出错误的最佳方法。如果您想要错误,请继续执行以下操作:
someObject.a.b.c; //...
我还使用一个内部递归函数实现了这一点,如下所示:
function get(obj, ns) {
function recurse(o, props) {
if (props.length === 0) {
return o;
}
if (!o) {
return undefined;
}
return recurse(o[props.shift()], props);
}
return recurse(obj, ns.split('.'));
}
这将返回ns参数指定的属性的深度值,否则,如果该属性不存在或在访问过程中出现任何问题,则将始终返回undefined。如果尝试访问空/未定义值的属性,则仍然会出现TypeError。……除了上述可能导致的其他灾难之外,这就是我不推荐它;)不得不说,我非常喜欢这样做。+1这样做的主要缺点是没有错误控制。如果我在节点路径中键入错误,将返回未定义的
,而您一点也不知道。这类似于使用PHP的@
操作符来达到相同的目的。@Andy,这是解决方案的本质。如果您想要错误,为什么不使用常规的呢查找(obj.a.b.c
)?无论如何,我已经用一种可能的补救方法编辑了答案。@J-P:这个问题要求一个接受动态级别数的解决方案。没有提到错误控制。但是,我可以看到某些情况下错误控制是没有用的,例如,在返回JSON深度可变的web服务中-我与thos合作过e before(易趣API浮现在脑海中)。您不必递归地检查某些内容是否存在,您可以在此处使用您的方法并检查未定义的内容,忽略它并继续。如果属性值为“falsy”,即0或false或“”或null,则此代码不会返回未定义的内容吗?这可能(也可能不是)你指的是JSON还是JavaScript对象?它们不一样。请注意,递归方法虽然更漂亮,但比迭代方法慢(至少在我的测试中)
someObject.a.b.c; //...
function get(obj, ns) {
function recurse(o, props) {
if (props.length === 0) {
return o;
}
if (!o) {
return undefined;
}
return recurse(o[props.shift()], props);
}
return recurse(obj, ns.split('.'));
}