动态深度选择JavaScript对象 [英] Dynamic deep selection for a JavaScript object

查看:76
本文介绍了动态深度选择JavaScript对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用单个属性这很容易:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆