在对象文字中捕获掉落的“未定义”刀?

时间:2011-04-22 18:51:28

标签: javascript

需要捕获对象文字的整个结构空间中的任何undefined。问题是undefined的位置无法预测:

.object    
     .result2[0] <--undefined could show its ugly face here, or anywhere above or below!
              .thumbnails[0]
                            .type
                                 .name
                                      .['open']

这不起作用:

if ( typeof object.result2[0].thumbnails[0].....  type == 'undefined'){     
    console.log("err'd out")
    handleError();
}

所以我想我正在寻找一个解决方案:如果object中的任何内容未定义做某事,或者我在咆哮错误的树?

4 个答案:

答案 0 :(得分:2)

通常你使用

if (object && object.result2[0] && object.results2[0].thumbnails[0] && object.results2[0].thumbnails[0].type && object.results2[0].thumbnails[0].type.name) {
    object.results2[0].thumbnails[0].type.name["open"] 
}

这看起来很丑陋的事实是你的嵌套问题,并且每个级别的事情都是不确定的。

答案 1 :(得分:2)

如果你真的想保持你的代码干净,你可以做一个简单的功能来检查是否存在所有密钥。

function pathExists() { // untested, but the basis is sound
    var obj = arguments[0], path = Array.prototype.slice.call(arguments, 1), cursor = obj;
    for (var i = 0; i < path.length; ++i) {
        if (typeof cursor[path[i]] == "undefined") return false;
        cursor = cursor[path[i]];
    }
    return cursor;
}

if (!pathExists(object, "result2", 0, "type", "name", "open")) 
   console.log("bork");

答案 2 :(得分:2)

如果你做了很多这样的事情,那么一个小帮助函数是有用的:

function dig_out(o, path, def) {
    var parts = path.split('.');
    for(var i = 0; i < parts.length; ++i) { 
        if(typeof o == 'undefined') 
            return def; 
        o = o[parts[i]];  
    }
    return o;
}
obj = { a: [1, [2, { b: 10 } ]]};
var x = dig_out(ob, 'a.1.1.b'); // x is now 10

诀窍是要意识到这一点:

object.results2[0].thumbnails[0].type.name["open"]

也可以写成:

object['results2'][0]['thumbnails'][0]['type']['name']['open']

这可以很容易地表示为字符串:

'results2.0.thumbnails.0.type.name.open'

易于理解和解析。

您也可以将路径表示为数组(如CD Sanchez所做),但是您必须使用默认值def执行某些操作。

您还可以允许path参数为数组:

function dig_out(o, path, def) {
    var parts = path instanceof Array ? path : path.split('.');
    for(var i = 0; i < parts.length; ++i) {
        if(typeof o == 'undefined')
            return def;
        o = o[parts[i]];
    }
    return o;
}
obj = { a: [1, [2, { b: 10 } ]]};
var x = dig_out(obj, 'a.1.1.b');        // x is now 10
var y = dig_out(obj, ['a', 1, 1, 'b']); // y is now 10

然后你可以灵活地选择哪种参数格式最容易使用,甚至不会花费太多。感谢CD Sanchez与这个想法的小讨论。

答案 3 :(得分:2)

简单的try-catch块可以解决这个问题,而无需测试每个级别。