JavaScript 中异常捕获可以只用 try{} 而不用 catch{} 吗?

我有一些函数,它们要么返回一些东西,要么抛出一个错误。在 main 函数中,我调用其中的每个函数,并希望返回每个函数返回的值,或者在第一个函数抛出错误时继续执行第二个函数。

所以基本上我现在拥有的是:

function testAll() {
try { return func1(); } catch(e) {}
try { return func2(); } catch(e) {} // If func1 throws error, try func2
try { return func3(); } catch(e) {} // If func2 throws error, try func3
}

但实际上我想只返回 try(即如果它没有抛出错误)。我不需要 catch块。但是,像 try {}这样的代码会失败,因为它缺少一个(未使用的) catch {}块。

我把 JsFiddle 上的一个例子

那么,有没有什么办法可以移除这些 catch块,同时达到同样的效果呢?

133601 次浏览

不,你必须留着它们。

这实际上是有意义的,因为错误根本不应该被无声地忽略。

不,catch(或 finally)是 try的朋友,并且总是作为 尝试/接住的一部分存在。

然而,像您的示例一样,将它们设置为空是完全有效的。

在示例代码(如果 fun1抛出错误,请尝试 fun2)中的注释中,似乎您真正想要做的是调用前面的 catch块中的下一个函数。

它们在我知道的所有有它们的语言(JavaScript,Java,C # ,C + +)中一起使用,不要这样做。

尝试和接住就像一个硬币的两面,所以不尝试是不可能的。

没有 接住子句的 试试看将其错误发送到下一个更高的 接住或窗口(如果在该尝试中没有定义 catch)。

如果没有 接住,则 try 表达式需要一个 终于子句。

try {
// whatever;
} finally {
// always runs
}

我决定从不同的角度来看待这个问题。

我已经能够确定一种方法,以便在部分处理另一个评论者列出的未处理的错误对象时,能够严格允许所请求的代码模式。

代码可见@http://jsfiddle.net/Abyssoft/RC7Nw/4/

Catch 被放置在 for 循环中,允许优雅地通过。同时能够遍历所需的所有函数。当需要显式错误处理时,使用附加函数数组。即使在错误和函数数组中带有错误处理程序的元素不是函数时,错误也被转储到控制台。

这里的每个 stackoverflow 需求都是内联的代码[经过编辑以使 JSLint 兼容(删除前导空格以进行确认) ,提高可读性]

function func1() {"use strict"; throw "I don't return anything"; }
function func2() {"use strict"; return 123; }
function func3() {"use strict"; throw "I don't return anything"; }


// ctr = Code to Run <array>, values = values <array>,
// eh = error code can be blank.
// ctr and params should match 1 <-> 1
// Data validation not done here simple POC
function testAll(ctr, values, eh) {
"use strict";
var cb; // cb = code block counter
for (cb in ctr) {
if (ctr.hasOwnProperty(cb)) {
try {
return ctr[cb](values[cb]);
} catch (e) {
if (typeof eh[cb] === "function") {
eh[cb](e);
} else {
//error intentionally/accidentially ignored
console.log(e);
}
}
}
}
return false;
}


window.alert(testAll([func1, func2, func3], [], []));

我不建议没有 catch 的 try-finally,因为在我自己的测试中,如果 try 块和 finally 块都抛出错误,那么 finally 子句中抛出的错误就会冒泡,try 块的错误就会被忽略:

try {
console.log('about to error, guys!');
throw new Error('eat me!');
} finally {
console.log ('finally, who cares');
throw new Error('finally error');
}

结果:

>     about to error, guys!
>     finally, who cares
>     .../error.js:9
>         throw new Error('finally error');
>         ^
>
>     Error: finally error

如果只希望在发生错误时激发函数2和3,为什么不将它们放在 catch 块中?

function testAll() {
try {
return func1();
} catch(e) {
try {
return func2();
} catch(e) {
try {
return func3();
} catch(e) {
// LOG EVERYTHING FAILED
}
}
}
}

由于 ES2019你可以很容易地使用没有 catch {}try {}:

try {
parseResult = JSON.parse(potentiallyMalformedJSON);
} catch (unused) {}

更多信息请参考 Michael Ficcara 的求婚

ES2019开始,可以有一个没有错误变量的空 catch 块。这称为 可选的捕捉绑定,在 V8 v6.6发布于2018年6月中实现。该功能已提供自 节点10一个 href = “ https://bugs.chromium.org/p/v8/problem/Details? id = 6889”rel = “ noReferrer”> Chrome 66 火狐58歌剧53Safari 11.1

语法如下:

try {
throw new Error("This won't show anything");
} catch { };

您仍然需要一个 catch块,但它可以是空的,并且不需要传递任何变量。如果根本不需要 catch 块,可以使用 try/finally,但是请注意,它不会像空 catch 那样吞噬错误。

try {
throw new Error("This WILL get logged");
} finally {
console.log("This syntax does not swallow errors");
}

不,没有 接住(或 终于)就不可能有 试试看块。作为一种解决方案,我相信您可能需要定义一个助手函数,如下所示:

function tryIt(fn, ...args) {
try {
return fn(...args);
} catch {}
}

然后像这样使用它:

tryIt(function1, /* args if any */);
tryIt(function2, /* args if any */);

看起来,没有; Javascript 需要一个 try 块后跟一个 catch 或 finally 块。

话虽如此,有一种方法可以达到 用那些挡板的效果你想要的。

如果抛出错误条件是 catch 块的用途。

既然它们的用途正是你想要的,为什么还要拿走它们呢?

try { return func1(); }
catch {
// if func1 throws error
try { return func2(); }
catch {
// if func2 throws error
try { return func3(); }
catch {
// if func3 throws error
}
}
}

我完全理解为什么您可能不需要 catch 块,并且会发现完全省略它更简单。但我不认为这是那种情况。