我如何区分不同类型的异常?

hel*_*hod 16 javascript

我开始学习JavaScript,到目前为止没问题,但我很难找到JS中的Exception机制的一个很好的解释.

它似乎与C++类似,JS允许抛出每个对象,而不是仅抛出一个Exception对象(可能是由于它的动态特性).

throw 'An error occured.';
Run Code Online (Sandbox Code Playgroud)

工作,以及

throw new Exception('An error occured.');
Run Code Online (Sandbox Code Playgroud)

catchfinally两个看起来像他们的Java等同于工作.不过,我不知道有哪些被广泛接受的关于例外的最佳做法.

因此,例如,抛出string类型的对象是否合法,如:

throw 'An error occured';
Run Code Online (Sandbox Code Playgroud)

我如何区分不同类型的异常?

And*_*y E 16

我想,"最佳实践"是抛出与导致异常的问题相关的正确类型的Error对象.ECMAScript定义了几种类型的异常对象,所有异常对象都继承自Error.这些对象是EvalError,RangeError,ReferenceError,TypeErrorURIError.

这些构造函数由本机ECMAScript函数使用,这使您可以执行以下操作:

try {
    // do something
}
catch (e) {
    if (e instanceof TypeError) {
        // do something else
    }
}
Run Code Online (Sandbox Code Playgroud)

通常,在throw不使用异常对象的情况下使用该语句会让我感觉不好,原因有多种,包括:

  • 设计用于处理异常的代码可能是期望一个Error对象,接收一个原语可能导致意外的副作用或无法处理异常而不修改处理代码.一个例子是stackthrow表达式的结果缺少一个属性.
  • 当未在try/catch语句中使用时,Internet Explorers 8及更低版本将在您尝试抛出时抛出另一个异常,并显示消息"抛出异常但未捕获" *.如果您使用开发人员工具进行调试或设置了全局异常处理程序,这可能会更加令人困惑window.onerror.

所以,是的,通常坚持正确地抛出实例Error或其继承对象.

*nb,IE也为不直接构造的Error对象类型执行此操作Error.是的,我知道这很愚蠢,但他们在IE 9中修复了它,即使他们告诉我它是"按设计".

  • `throw <String>`是一个反模式,仅仅是因为`catch`中返回的错误没有`.stack`属性,如果它不是真正的`Error`实例而且是纯粹的RAGE.另外,try/catch/throw是JS中的一般性能反模式,应该尽可能避免. (7认同)

Mik*_*sen 12

抛出和捕获异常是非常昂贵的,并且使用JavaScript时,在尝试解析格式错误的JSON字符串时,您将主要获得异常.我建议尽可能避免try/catch,而是专注于以旧方式检查错误(返回类型,确保变量在使用之前正确初始化等等),因为异常在这里不太可能发生在C++中或者特别是Java或.NET.

Andy E的建议对于实际处理它们是一个很好的建议,但一般来说,你应该尝试防御性地编写JavaScript代码,这样你甚至不需要try/catch.请记住,即使是与Java或C#相比,Chrome中的JITed JavaScript(速度最快的引擎)仍然很慢,更不用说C++了,所以在JavaScript中,这些语言中的任何一种代价都可能更高.