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


当前回答

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

其他回答

使用throw语句。

JavaScript并不关心异常类型(就像Java一样)。 JavaScript只是注意到,有一个异常,当你捕捉到它,你可以“看看”异常“说”什么。

如果你有不同的异常类型,你必须抛出,我建议使用变量包含异常的字符串/对象,即消息。在需要它的地方使用“throw myException”,在catch中,将捕获的异常与myException进行比较。

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

请参见MDN中的示例。

如果你需要定义多个error(在这里测试代码!):

function createErrorType(name, initFunction) {
    function E(message) {
        this.message = message;
        if (Error.captureStackTrace)
            Error.captureStackTrace(this, this.constructor);
        else
            this.stack = (new Error()).stack;
        initFunction && initFunction.apply(this, arguments);
    }
    E.prototype = Object.create(Error.prototype);
    E.prototype.name = name;
    E.prototype.constructor = E;
    return E;
}
var InvalidStateError = createErrorType(
    'InvalidStateError',
    function (invalidState, acceptedStates) {
        this.message = 'The state ' + invalidState + ' is invalid. Expected ' + acceptedStates + '.';
    });

var error = new InvalidStateError('foo', 'bar or baz');
function assert(condition) { if (!condition) throw new Error(); }
assert(error.message);
assert(error instanceof InvalidStateError);  
assert(error instanceof Error); 
assert(error.name == 'InvalidStateError');
assert(error.stack);
error.message;

在JavaScript中,什么是扩展错误的好方法?

ES6

使用新的类和扩展关键字,现在更容易:

class CustomError extends Error {
  constructor(message) {
    super(message);
    //something
  }
}

你应该创建一个扩展Error的自定义异常:

class InvalidArgumentException extends Error {
  constructor(message) {
    super(message);
    this.name = this.constructor.name;
  }
}

注意:设置this.name是. tostring()和.stack打印InvalidArgumentException而不是Error所必需的。

对于旧的Javascript环境,你可以做原型继承:

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;

这基本上是一个简化版本的disfated与增强堆栈跟踪工作在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!