为何throw new Error会终止执行,而try-catch内抛出错误却不会?
JavaScript中throw错误的执行终止规则
先看你给出的两个示例:
第一个示例:
throw new Error(); console.log("Hello"); // This never runs
这里的错误没有被任何代码捕获,属于未捕获异常,JavaScript引擎会直接中断当前执行栈,后续代码完全不会执行。
第二个示例:
function addTwoNums(a, b) { try { if (typeof a != "number") { throw new ReferenceError("The first argument is not a number"); } else if (typeof b != "number") { throw new ReferenceError("The second argument is not a number"); } else { console.log(a + b); } } catch (error) { console.log("Error:", error.message); } } addTwoNums("100", 100); console.log("This is still runs normally!");
这里的错误被try-catch结构中的catch块捕获并处理了,执行流程会从catch块结束后继续往下走,不会中断整个程序。
问题解答
- 为什么两种场景执行结果不同?
JavaScript的错误处理逻辑是:当抛出一个错误时,引擎会沿着当前执行栈向上查找最近的catch块来处理这个错误。
- 如果找不到任何
catch块(比如第一个示例直接在全局作用域throw),这个错误就会变成未捕获异常,引擎会终止当前执行栈的所有后续代码,甚至可能导致整个脚本停止运行。 - 如果找到了对应的
catch块(第二个示例的情况),引擎会跳转到catch块执行错误处理逻辑,执行完catch后,会继续执行try-catch结构之后的代码,不会影响外部的执行流程。
- 是否只有当错误在try-catch内被处理时,throw才不会终止执行?
是的,在同步代码场景下,只有当错误被try-catch(或者嵌套的try-catch)捕获处理时,throw才不会导致整个程序终止。
如果错误没有被任何catch捕获,不管是直接在全局作用域抛出,还是在函数内部抛出但函数调用时没有用try-catch包裹,都会触发未捕获异常,终止后续代码执行。
补充说明:对于异步代码中的错误(比如setTimeout里的throw),普通的try-catch无法捕获,需要用异步错误处理方式(比如async/await配合try-catch,或者Promise的catch方法),否则同样会变成未捕获异常。
内容的提问来源于stack exchange,提问作者Saoud ElTelawy
相关产品推荐
相关产品推荐

