我可以在JavaScript中为用户定义的异常定义自定义类型吗?如果是,我该怎么做?
当前回答
是的。你可以抛出任何你想抛出的东西:整数、字符串、对象等等。如果要抛出一个对象,那么只需创建一个新对象,就像在其他情况下创建一个对象一样,然后抛出它。Mozilla的Javascript参考中有几个例子。
其他回答
下面是如何创建与本机错误行为完全相同的自定义错误。这项技术目前只适用于Chrome和node.js。如果你不理解它的功能,我也不建议你使用它。
Error.createCustromConstructor = (function() {
function define(obj, prop, value) {
Object.defineProperty(obj, prop, {
value: value,
configurable: true,
enumerable: false,
writable: true
});
}
return function(name, init, proto) {
var CustomError;
proto = proto || {};
function build(message) {
var self = this instanceof CustomError
? this
: Object.create(CustomError.prototype);
Error.apply(self, arguments);
Error.captureStackTrace(self, CustomError);
if (message != undefined) {
define(self, 'message', String(message));
}
define(self, 'arguments', undefined);
define(self, 'type', undefined);
if (typeof init == 'function') {
init.apply(self, arguments);
}
return self;
}
eval('CustomError = function ' + name + '() {' +
'return build.apply(this, arguments); }');
CustomError.prototype = Object.create(Error.prototype);
define(CustomError.prototype, 'constructor', CustomError);
for (var key in proto) {
define(CustomError.prototype, key, proto[key]);
}
Object.defineProperty(CustomError.prototype, 'name', { value: name });
return CustomError;
}
})();
结果我们得到
/**
* name The name of the constructor name
* init User-defined initialization function
* proto It's enumerable members will be added to
* prototype of created constructor
**/
Error.createCustromConstructor = function(name, init, proto)
然后你可以这样使用它:
var NotImplementedError = Error.createCustromConstructor('NotImplementedError');
并使用NotImplementedError,就像你会错误:
throw new NotImplementedError();
var err = new NotImplementedError();
var err = NotImplementedError('Not yet...');
它的行为是预期的:
err instanceof NotImplementedError // -> true
err instanceof Error // -> true
NotImplementedError.prototype.isPrototypeOf(err) // -> true
Error.prototype.isPrototypeOf(err) // -> true
err.constructor.name // -> NotImplementedError
err.name // -> NotImplementedError
err.message // -> Not yet...
err.toString() // -> NotImplementedError: Not yet...
err.stack // -> works fine!
注意,这个错误。堆栈工作绝对正确,不会包括NotImplementedError构造函数调用(感谢v8的Error.captureStackTrace())。
请注意。有难看的eval()。使用它的唯一原因是得到正确的err.constructor.name。如果你不需要它,你可以简化一切。
//create error object
var error = new Object();
error.reason="some reason!";
//business function
function exception(){
try{
throw error;
}catch(err){
err.reason;
}
}
现在我们设置,添加原因或任何我们想要的属性到错误对象并检索它。通过使误差更合理。
请参见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中,什么是扩展错误的好方法?
你应该创建一个扩展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!
你可以实现你自己的异常和它们的处理,例如:
// 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");
}
推荐文章
- 导致java.lang.VerifyError错误的原因
- 错误:'types'只能在.ts文件中使用- Visual Studio Code使用@ts-check
- React-Native:应用程序未注册错误
- LoDash:从对象属性数组中获取值数组
- src和dist文件夹的作用是什么?
- jQuery UI对话框-缺少关闭图标
- 如何使用AngularJS获取url参数
- 将RGB转换为白色的RGBA
- 如何将“camelCase”转换为“Camel Case”?
- 我们可以在另一个JS文件中调用用一个JavaScript编写的函数吗?
- 如何使用JavaScript重新加载ReCaptcha ?
- jQuery。由于转义了JSON中的单引号,parseJSON抛出“无效JSON”错误
- 在JavaScript关联数组中动态创建键
- ReactJS和公共文件夹中的图像
- 在React Native中使用Fetch授权头