自定义异常类型

IT技术 javascript exception
2021-03-16 22:14:12

我可以在 JavaScript 中为用户定义的异常定义自定义类型吗?如果是这样,我该怎么做?

6个回答

Web引用

throw { 
  name:        "System Error", 
  level:       "Show Stopper", 
  message:     "Error detected. Please contact the system administrator.", 
  htmlMessage: "Error detected. Please contact the <a href=\"mailto:sysadmin@acme-widgets.com\">system administrator</a>.",
  toString:    function(){return this.name + ": " + this.message;} 
}; 
@b.long 它在“JavaScript: The Good Parts”(IMO 好书)中。此 Google 图书预览显示了以下部分:books.google.com/books?id=PXa2bby0oQ0C&pg=PA32&lpg=PA32
2021-04-23 22:14:12
添加 toString 方法将使其在 javascript 控制台中很好地显示。如果没有它,则显示为:未捕获的 #<Object> 带有 toString,它显示为:未捕获的系统错误:检测到错误。请联系系统管理员。
2021-04-27 22:14:12
除非您从 Error 继承,否则这将不允许您进行堆栈跟踪
2021-04-27 22:14:12
如何在 catch 块中过滤以仅处理此自定义错误?
2021-05-08 22:14:12
这不解释如何创建用户定义的异常。-1 因为只有代码没有解释。这些字段是必填的吗?这些字段是可选的吗?toString()函数对某些浏览器或某些其他 JavaScript 函数是否具有特定含义?等等。
2021-05-15 22:14:12

您应该创建一个典型地从 Error 继承的自定义异常。例如:

function InvalidArgumentException(message) {
    this.message = message;
    // Use V8's native method if available, otherwise fallback
    if ("captureStackTrace" in Error)
        Error.captureStackTrace(this, InvalidArgumentException);
    else
        this.stack = (new Error()).stack;
}

InvalidArgumentException.prototype = Object.create(Error.prototype);
InvalidArgumentException.prototype.name = "InvalidArgumentException";
InvalidArgumentException.prototype.constructor = InvalidArgumentException;

这基本上是上面发布的内容的简化版本,增强了堆栈跟踪在 Firefox 和其他浏览器上的工作。它满足他发布的相同测试:

用法:

throw new InvalidArgumentException();
var err = new InvalidArgumentException("Not yet...");

它的行为是预期的:

err instanceof InvalidArgumentException          // -> true
err instanceof Error                             // -> true
InvalidArgumentException.prototype.isPrototypeOf(err) // -> true
Error.prototype.isPrototypeOf(err)               // -> true
err.constructor.name                             // -> InvalidArgumentException
err.name                                         // -> InvalidArgumentException
err.message                                      // -> Not yet...
err.toString()                                   // -> InvalidArgumentException: Not yet...
err.stack                                        // -> works fine!
更加灵活和可扩展。
2021-04-30 22:14:12

您可以实现自己的异常及其处理,例如:

// define exceptions "classes" 
function NotNumberException() {}
function NotPositiveNumberException() {}

// try some code
try {
    // some function/code that can throw
    if (isNaN(value))
        throw new NotNumberException();
    else
    if (value < 0)
        throw new NotPositiveNumberException();
}
catch (e) {
    if (e instanceof NotNumberException) {
        alert("not a number");
    }
    else
    if (e instanceof NotPositiveNumberException) {
        alert("not a positive number");
    }
}

还有另一种捕获类型异常的语法,尽管这不适用于所有浏览器(例如不适用于 IE):

// define exceptions "classes" 
function NotNumberException() {}
function NotPositiveNumberException() {}

// try some code
try {
    // some function/code that can throw
    if (isNaN(value))
        throw new NotNumberException();
    else
    if (value < 0)
        throw new NotPositiveNumberException();
}
catch (e if e instanceof NotNumberException) {
    alert("not a number");
}
catch (e if e instanceof NotPositiveNumberException) {
    alert("not a positive number");
}
MSN 网站带有有关条件捕获的警告:非标准此功能是非标准的,不在标准轨道上。不要在面向 Web 的生产站点上使用它:它不适用于每个用户。实现之间也可能存在很大的不兼容性,未来可能会改变行为。
2021-04-23 22:14:12

是的。你可以抛出任何你想要的东西:整数、字符串、对象等等。如果你想抛出一个对象,那么只需创建一个新对象,就像在其他情况下创建一个对象一样,然后抛出它。Mozilla 的 Javascript 参考有几个例子。

function MyError(message) {
 this.message = message;
}

MyError.prototype = new Error;

这允许使用像..

try {
  something();
 } catch(e) {
  if(e instanceof MyError)
   doSomethingElse();
  else if(e instanceof Error)
   andNowForSomethingCompletelyDifferent();
}
的确。但既然e instanceof MyError是真的,则else if(e instanceof Error)永远不会评估语句。
2021-04-26 22:14:12
即使您没有继承 Error 的原型,这个简短的示例难道不会以完全相同的方式工作吗?我不清楚在这个例子中你得到了什么。
2021-04-30 22:14:12
不,e instanceof Error会是假的。
2021-05-09 22:14:12
是的,这只是说明这种 try/catch 风格如何工作的示例。哪里else if(e instanceof Error)会是最后一次捕获。可能后跟一个简单的else(我没有包括在内)。有点像default:switch 语句中的 ,但有错误。
2021-05-16 22:14:12