Dynamic deep selection for a JavaScript object

前端 未结 4 1101
伪装坚强ぢ
伪装坚强ぢ 2020-12-30 12:54

With a single property this is fairly easy:


var jsonobj = {
    \"test\": \"ok\"
}
var propname = \"test\";
// Will alert \"ok\"
alert(jsonobj[propname]);
<         


        
4条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-12-30 13:44

    function resolve(cur, ns) {
    
        var undef;
    
        ns = ns.split('.');
    
        while (cur && ns[0])
            cur = cur[ns.shift()] || undef;
    
        return cur;
    
    }
    

    E.g.

    // 1:
    resolve({
        foo: { bar: 123 }
    }, 'foo.bar'); // => 123
    
    
    // 2:
    var complex = {
        a: {
            b: [
                document.createElement('div')
            ]
        }
    };
    
    resolve(complex, 'a.b.0.nodeName'); // => DIV
    

    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.


    EDIT:

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

    It'll return an UNRESOLVED object that can be checked like so:

    var result = resolve(someObject, 'a.b.c');
    
    if (result === resolve.UNRESOLVED) {...}
    

    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; //...
    

提交回复
热议问题