The Error class includes debugging information (as properties of its instances), such as the error's call stack. JS interpreters know how to serialise those properties into an informative error message string, and they can also be consumed by debugging software - such as browser dev tools - to construct a more informative GUI representation of the error. This is why it's generally more useful to throw an instance of the Error class rather than simply throwing, for example, a string describing the error, or a number representing an error code.
使用自定义错误
特别有用的是创建自己的Error子类,它允许您使用描述性名称和机器可读的惟一标识不同类型的错误……
调试线索,
信息,以便更好地面向用户的错误消息,或者
帮助从错误中恢复的信息。
然后,在处理错误时,可以使用简洁的instanceof操作符来检查发生了什么类型的错误。例如:
class ShoesTooBig extends Error {}
class DangerousWaterCurrent extends Error {
constructor(waterSpeed){
super(`These waters are moving at ${waterSpeed} metres per second - too fast to cross!`) // Provide a `message` argument to the Error() constructor
this.waterSpeed = waterSpeed // This passes some context about why/how the error occurred back to whichever function is going to catch & handle it
}
}
// ...later...
try {
swimAcrossRiver(footwear, river)
} catch (thrownValue) {
if (thrownValue instanceof DangerousWaterCurrent) {
constructDam(river, thrownValue.waterSpeed)
} else {
throw thrownValue // "Re-throw" the error back up the execution chain, for someone else to handle
}
}
new Error() vs Error()
There is a "convenient" shorthand way to make an instance of Error: by calling Error(message), instead of new Error(message), the way you'd make an instance of a normal class. This is a deliberate exception, inserted by the language designers, to the rule. There are similar shorthands for other in-language classes, like Number() and String(). They also let you call these classes with () as if they were functions, not classes. JS doesn't allow normal classes to do this, even though they're all actually functions under the syntactical sugar of "classes". Try in a REPL:
> class E extends Error {}
undefined
> Error(); 'a value'
"a value"
> E(); 'a value'
Uncaught TypeError: Class constructor E cannot be invoked without 'new'
at <anonymous>:2:1
就我个人而言,我认为这个决定是错误的,因为它为JavaScript规则添加了更多的例外。而不是c++ /Java的new关键字,简单地调用一个类,就好像它是一个函数(如在Number("abc123")))应该执行类的构造函数,并将其绑定到实例,就像通常发生的new关键字一样(这是Python的语法工作方式,它最终更易于阅读和方便)。