Javascript 抛出字符串而不是错误
既然我们可以在Javascript中抛出任何带有Javascript 抛出字符串而不是错误,javascript,Javascript,既然我们可以在Javascript中抛出任何带有throw关键字的东西,我们就不能直接抛出一个错误消息字符串吗 有人知道这里面有什么陷阱吗 让我添加一些背景知识:在JavaScript世界中,人们通常依赖于参数检查,而不是使用try-catch机制,因此只使用throw抛出致命错误是有意义的。尽管如此,为了能够捕获一些系统错误,我必须为自己的错误使用不同的类,而不是创建错误的子类,我认为我应该只使用String。您可以通过消息抛出错误,您知道 try { throw new Error(
throw
关键字的东西,我们就不能直接抛出一个错误消息字符串吗
有人知道这里面有什么陷阱吗
让我添加一些背景知识:在JavaScript世界中,人们通常依赖于参数检查,而不是使用try-catch机制,因此只使用
throw
抛出致命错误是有意义的。尽管如此,为了能够捕获一些系统错误,我必须为自己的错误使用不同的类,而不是创建错误的子类,我认为我应该只使用String。您可以通过消息抛出错误,您知道
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
}
虽然可以抛出任何值,但通常认为抛出除Error
或其子类之外的任何值都是不好的。这有几个原因:
错误上的消息
、堆栈跟踪
和名称
属性
错误
对象的属性提供
每当你想抛出一个基本字符串值时,就抛出一个新的错误(“”。正如上面其他人所提到的,如果你没有抛出一个错误对象,那么你必须有try/catch块来捕获这些对象并适当地处理它们,否则调试就会受到伤害 然而,当涉及到为控制程序流等非错误处理目的抛出错误时,这可能是一种利用
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
}
}
尽管您可以抛出您想要的任何类型的数据,但在调试时这并不是最优的。JS
Error
对象包含有关错误和消息的所有信息。而字符串只能包含消息
这些额外信息包括:
虽然这是可能的,但它有意义吗?我宁愿捕获错误而不是字符串。相关:exports.login=(req,res)=>{login(req)。然后({token,user})=>{res.send(token);})。catch(err=>{if(typeof err=='string'){res status(401)。send(err);}else{console.log(err);res.status(500)。send(‘出了点问题’;}});}我确实是这样处理错误的,我也很困惑,我做得对吗?很抱歉没有把问题说清楚。我知道这些都是有效的,但我对直接使用字符串而不是使用错误对象的潜在问题感兴趣。啊,好吧,那就看看Ianzz的评论。它总结了所有的注意事项。但是我的建议是仍然是抛出带有自定义消息的
错误
对象。这样就省去了检查错误类型以将“您的”错误与其他本机生成的错误区分开来的麻烦…当然,除非您有意这样做(然后可能会在捕获
范围中重新抛出错误
对象)。值得注意的是,即使您抛出字符串,Chrome devtools也会打印堆栈跟踪。您将丢失.stack
属性,该属性对于某些自动错误处理非常有用(例如,当设置自动向服务器报告错误以允许您调试生产中出现的错误时),但这更像是一种边缘情况;如果抛出字符串,则浏览器中的日常手动调试工作正常。例如,它可能会假定的.message
属性是字符串,尝试对其调用string方法,然后分解。可以,但我不会说它“OK”。这是一个糟糕的想法,因为这意味着在没有堆栈跟踪的情况下调试bug要困难得多。@BenjaminGruenbaum如果你在Chrome中抛出一个字符串,你确实会得到一个堆栈跟踪。例如`function a(){throw“Hello World”}a();`将有如下堆栈跟踪:a@main.js:4(匿名)@main.js:7
@Taurus谢谢,我不知道-现在尝试使用firefox中未连接的调试器执行此操作:)不,如果需要驱动程序流,请使用可以处理程序流的值返回/解析。例外是例外。如果您无法恢复并且需要系统抛出异常,那么这不是程序流,而是异常处理。我同意,除了异常处理之外,不应抛出错误和异常。然而,在我的示例中,我只是抛出一个对象,而不是实例化一个错误,因此它只是u