Javascript 在这种情况下使用异常处理好吗?

Javascript 在这种情况下使用异常处理好吗?,javascript,exception-handling,Javascript,Exception Handling,我在JavaScript中使用这种代码 if(typeof a[x] != "undefined" && typeof a[x][y] != "undefined" && typeof a[x][y][z] != "undefined") { a[x][y][z].update(); } // else do nothing 我只是认为使用try-catch实现上述逻辑将简化代码,并减少每次对三个条件的检查。(见下文) 在这种情况下使用try-catch

我在JavaScript中使用这种代码

if(typeof a[x] != "undefined" && typeof a[x][y] != "undefined" && typeof a[x][y][z] != "undefined") {
    a[x][y][z].update();
}
// else do nothing
我只是认为使用try-catch实现上述逻辑将简化代码,并减少每次对三个条件的检查。(见下文)

在这种情况下使用try-catch好吗


注意:如果您想知道我为什么要检查这三个条件:a[][]包含对对象的引用,并且引用是动态添加的。

.update()
方法引发的任何异常都会被静默忽略,可能隐藏bug。请注意,在原始示例中,您不必使用
typeof

if(a[x] !== undefined && a[x][y] !== undefined && a[x][y][z] !== undefined) {
    a[x][y][z].update();
}

为什么要显式检查未定义

if(a[x] && a[x][y] && a[x][y][z]) {
    a[x][y][z].update();
}

可读性更为重要,除非您处于一个性能极其优化的循环或函数中,否则它不会有什么不同

正如PleaseStand所说,将整个内容包装在
try/catch
中将隐藏任何错误。如果您仍然想
try/catch

var fn = null;

try {
    fn = a[x][y][z].update;
} catch (e) {
    fn = function(){}
}

fn();


Javascript在处理虚假值时非常容错,您可以执行以下操作:

var v = 
    (a ? (a[x] 
           ? (a[x][y] 
               ? (a[x][y][z] 
                   ? a[x][y][z] : null) 
               : null) 
           : null) 
    : null);

if (v) v.update();
在这种情况下使用try-catch好吗

不,因为它将捕获并丢弃除预期错误之外的任何其他错误,从而使调试更加困难。不幸的是,JavaScript的异常处理能力相当弱,无法仅捕获某些异常。相反,你必须抓住一切,故意嗅探你想要的,然后重新扔掉剩下的:

try {
    a[x][y][z].update();
} catch(e) {
    if (!(e instanceof TypeError))
        throw e;
}
这还不是很清楚,并且仍然会捕获很多其他潜在的错误,因为JavaScript的内置异常(如
TypeError
)非常广泛

除了在操作符中使用更显式的
而不是笨重的
typeof
测试之外,我会选择您最初的解决方案:

if (x in a && y in a[x] && z in a[x][y])
    a[x][y][z].update();

当出现其他错误时,
try
方法也会
catch
,因此我不会使用它。@pimvdb:???你指的是什么其他错误?@Kooilnc:比如
.update()
函数中发生的错误。我不知道该函数实际上在做什么,但是
try/catch
会抑制该行代码或在那里调用的其他函数中发生的所有错误。+1注意,
undefined
可以设置为其他值,因此
typeof
更可靠。哦,我不知道这一点。对于正常变量!==undefined不起作用,但它适用于数组。为什么会这样?@pimvdb我不明白您将undefined设置为其他值是什么意思。undefined=123???自己试试:
undefined=123;var foo=未定义。现在
foo===未定义
但是
typeof foo!=='未定义“
@Cronco”。我看不出在哪些情况下中间值是错误的,而[x][y][z].update()是可运行的。有什么例子吗?我想不出现场有什么例子,但可以肯定的是,计算某些东西在某个时候可能需要0作为输入。@Cronco。当然,0通常是一个有效的输出,但在这里您将执行0[something]或0.update()
try {
    a[x][y][z].update();
} catch(e) {
    if (!(e instanceof TypeError))
        throw e;
}
if (x in a && y in a[x] && z in a[x][y])
    a[x][y][z].update();