【问题标题】:How would I differentiate between different types of exceptions? [closed]我将如何区分不同类型的异常? [关闭]
【发布时间】:2012-01-24 12:40:36
【问题描述】:

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

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

throw 'An error occured.';

工作,以及

throw new Exception('An error occured.');

catchfinally 似乎都像它们的 Java 等效项一样工作。不过,我不知道在异常方面有哪些被广泛接受的最佳实践。

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

throw 'An error occured';

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

【问题讨论】:

  • 您必须缩小您的问题范围。最佳实践是什么?

标签: javascript


【解决方案1】:

我想,“最佳实践”是抛出与导致异常的问题相关的正确类型的 Error 对象。 ECMAScript 定义了几种类型的异常对象,它们都继承自Error。这些对象是EvalErrorRangeErrorReferenceErrorTypeErrorURIError

原生 ECMAScript 函数使用这些构造函数,这使您可以执行以下操作:

try {
    // do something
}
catch (e) {
    if (e instanceof TypeError) {
        // do something else
    }
}

一般来说,使用throw 语句而不使用异常对象让我觉得这种做法很糟糕,原因有几个,包括:

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

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

*nb,IE 也对不直接从Error 构造的错误对象类型执行此操作。是的,我知道这很愚蠢,但他们在 IE 9 中修复了它,尽管他们告诉我这是“设计使然”。

【讨论】:

  • throw <String> 是一种反模式,仅仅是因为catch 中返回的错误没有.stack 属性,如果它不是真正的Error 实例,那是纯粹的RAGE。顺便说一句,try/catch/throw 是 JS 中的一种通用性能反模式,应尽可能避免。
【解决方案2】:

抛出和捕获异常非常昂贵,而使用 JavaScript,您主要会在尝试解析格式错误的 JSON 字符串等情况下获得异常。我建议尽可能避免尝试/捕获,而是专注于以老式方式检查错误(返回类型,确保变量在使用之前正确初始化等),因为这里发生异常的可能性低于 C++尤其是 Java 或 .NET。

Andy E's recommendation 非常适合实际处理它们,但一般来说,您应该尝试防御性地编写 JavaScript 代码,这样您甚至不需要 try/catch。请记住,即使是 Chrome(最快的引擎)中的 JITed JavaScript 与 Java 或 C# 相比仍然很慢,更不用说 C++,所以在这些语言中昂贵的东西在 JavaScript 中可能更是如此。

【讨论】:

  • +1,我没有想到要完全反对 try/catch 语句,尽管我很少需要写一个。您可能需要 try/catch 的原因之一是在处理可能不存在或无法实例化的主机对象(如 IE 的 ActiveXObjects)时。
【解决方案3】:

如果您正在构建 AJAX 应用程序 - 异常可能没有那么有用。由于 ajax 操作的异步特性,错误处理不会像您预期的那样工作

function save_data(){
    try {
        ajax(some_ulr, function(){
            //callback
            do_wrong_thing();
        });
    } catch(e){
        handler_error();
    }
}

在上面的代码sn-p中,do_wrong_thing引起的错误不会触发catch部分。

【讨论】:

  • 异步代码也破坏了return,所以这应该是意料之中的......
猜你喜欢
  • 1970-01-01
  • 2016-03-20
  • 1970-01-01
  • 1970-01-01
  • 2018-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多