94

既然我们可以用throwJavascript 中的关键字抛出任何东西,那么我们不能直接抛出一个错误消息字符串吗?

有谁知道这有什么问题?

让我补充一些背景知识:在 JavaScript 世界中,人们经常依赖参数检查而不是使用 try-catch 机制,因此只使用throw. 尽管如此,为了能够捕获一些系统错误,我必须为自己的错误使用不同的类,而不是创建错误的子类,我认为我应该只使用字符串。

4

5 回答 5

69

虽然可以抛出任何值,但通常认为抛出除了实例Error或其子类之一之外的任何东西都是糟糕的形式。有几个原因:

  1. 捕获代码可能期望抛出的对象具有出现在s上的常用messagestacktrace和属性。nameError
  2. 缺少堆栈跟踪会使调试出现问题,尤其是在未捕获的异常/未处理的拒绝的情况下。例如,调试“Uncaught [Object object]”错误可能特别痛苦。
于 2012-07-16T21:10:26.620 回答
60

是的,您可以抛出其他值,但这不是一个好习惯

有谁知道这有什么问题?

字符串不是错误对象,不传达任何有用的调试信息。Devtools 依赖于它,例如创建错误的文件和行、该throw位置的堆栈跟踪等,这些都可以作为对象的属性使用Error

每当您想到抛出原始字符串值时,请new Error("<the string>")改为抛出 a。

于 2014-12-16T09:29:40.453 回答
22

你可以用消息抛出错误,你知道的。

try {
    throw new Error("This is an error");
} catch (e) {
    alert(e.message); // This is an error
}

但你实际上可以抛出字符串:

try {
    throw "This is an error";
} catch (e) {
    alert(e); // This is an error
}
于 2012-07-16T09:59:11.020 回答
5

正如其他人在上面提到的那样,如果您没有抛出 Error 对象,那么您必须有 try/catch 块来捕获这些对象并适当地处理它们,否则会在调试时受到伤害。

然而,当涉及到为了控制程序流等非错误处理目的而抛出错误时,这可能是一种在throw没有错误的情况下使用的有用方法。

当使用 throws 来控制程序流时,它在任何语言中都可能是低效的,因为运行时通常会做很多繁重的工作来展开调用堆栈信息并序列化数据,以便它在用户范围内可用。通过避免创建错误,您可以避免这种性能损失。关键是您必须在调用堆栈中有一个处理程序,该处理程序知道如何处理这种情况。例如,如果您throw {isHardStop: true, stopCode: SOME_CODE}设计处理程序来检测这一点,您可能能够扁平化您的一些代码或选择更简洁的语法。

这个梯子案例的处理程序的结构可能如下:

try { ... } catch(thr) {
    if(!thr){
       // Is not Error or Json - Handle accordingly
    } else if(thr.isHardStop){
       // Handle the stop
    } else {
       // Most likely a real error. Handle accordingly
    }
}
于 2015-08-20T16:42:49.450 回答
3

尽管您可以抛出任何类型的数据,但在调试时这并不是最佳选择。一个 JSError对象包含有关错误和消息的所有类型的信息。而字符串只能包含一条消息。

此附加信息包括:

  1. fileName:从哪个文件抛出错误
  2. Linenumber : 从哪一行抛出错误
  3. stacktrace:从哪个函数调用了错误

例如,来自 chrome devtools 的堆栈跟踪:

在此处输入图像描述

于 2019-07-17T13:36:30.983 回答