我可以在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();
}
其他回答
使用throw语句。
JavaScript并不关心异常类型(就像Java一样)。 JavaScript只是注意到,有一个异常,当你捕捉到它,你可以“看看”异常“说”什么。
如果你有不同的异常类型,你必须抛出,我建议使用变量包含异常的字符串/对象,即消息。在需要它的地方使用“throw myException”,在catch中,将捕获的异常与myException进行比较。
ES6
使用新的类和扩展关键字,现在更容易:
class CustomError extends Error {
constructor(message) {
super(message);
//something
}
}
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();
}
你应该创建一个扩展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!
我经常使用带有原型继承的方法。重写toString()的好处是,像Firebug这样的工具将记录实际信息,而不是将[object object]记录到控制台,以查找未捕获的异常。
使用instanceof来确定异常的类型。
main.js
// just an exemplary namespace
var ns = ns || {};
// include JavaScript of the following
// source files here (e.g. by concatenation)
var someId = 42;
throw new ns.DuplicateIdException('Another item with ID ' +
someId + ' has been created');
// Firebug console:
// uncaught exception: [Duplicate ID] Another item with ID 42 has been created
Exception.js
ns.Exception = function() {
}
/**
* Form a string of relevant information.
*
* When providing this method, tools like Firebug show the returned
* string instead of [object Object] for uncaught exceptions.
*
* @return {String} information about the exception
*/
ns.Exception.prototype.toString = function() {
var name = this.name || 'unknown';
var message = this.message || 'no description';
return '[' + name + '] ' + message;
};
DuplicateIdException.js
ns.DuplicateIdException = function(message) {
this.name = 'Duplicate ID';
this.message = message;
};
ns.DuplicateIdException.prototype = new ns.Exception();