在JS中,似乎不可能检查传递给函数的参数是否实际为'error'类型或error实例。
例如,这是无效的:
Typeof err === 'error'
因为只有6种可能的类型(以字符串的形式):
typeof操作符以字符串形式返回类型信息。typeof返回六种可能的值:
“数字”,“字符串”,“布尔”,“对象”,“函数”和“未定义”。
MSDN
但如果我有一个简单的用例,像这样:
function errorHandler(err) {
if (typeof err === 'error') {
throw err;
}
else {
console.error('Unexpectedly, no error was passed to error handler. But here is the message:',err);
}
}
那么,确定参数是否为Error实例的最佳方法是什么呢?
instanceof操作符有什么帮助吗?
你可以使用object .prototype. tostring来检查一个对象是否为Error,这也适用于不同的帧。
function isError(obj){
return Object.prototype.toString.call(obj) === "[object Error]";
}
函数返回错误(obj) {
return object .prototype. tostring .call(obj) === "[对象错误]";
}
console.log("Error:", isError(new Error));
console.log("RangeError:", isError(new RangeError));
console.log("SyntaxError:", isError(new SyntaxError));
console.log(“对象:”,返回错误({}));
console.log(“数组:",返回错误([]));
此行为由ECMAScript语言规范保证。
Object.prototype.toString:
当调用toString方法时,执行以下步骤:
如果this值未定义,则返回“[object undefined]”。
如果此值为空,则返回“[object null]”。
设O为调用ToObject的结果,并将this值作为参数传递。
设class为O的[[class]]内部属性的值。
返回String值,这是连接三个String "[object ", class和"]"的结果。
错误实例的属性:
Error实例从Error原型对象继承属性,它们的[[Class]]内部属性值为"Error"。错误实例没有特殊属性。
你可以使用object .prototype. tostring来检查一个对象是否为Error,这也适用于不同的帧。
function isError(obj){
return Object.prototype.toString.call(obj) === "[object Error]";
}
函数返回错误(obj) {
return object .prototype. tostring .call(obj) === "[对象错误]";
}
console.log("Error:", isError(new Error));
console.log("RangeError:", isError(new RangeError));
console.log("SyntaxError:", isError(new SyntaxError));
console.log(“对象:”,返回错误({}));
console.log(“数组:",返回错误([]));
此行为由ECMAScript语言规范保证。
Object.prototype.toString:
当调用toString方法时,执行以下步骤:
如果this值未定义,则返回“[object undefined]”。
如果此值为空,则返回“[object null]”。
设O为调用ToObject的结果,并将this值作为参数传递。
设class为O的[[class]]内部属性的值。
返回String值,这是连接三个String "[object ", class和"]"的结果。
错误实例的属性:
Error实例从Error原型对象继承属性,它们的[[Class]]内部属性值为"Error"。错误实例没有特殊属性。
我问了最初的问题——@Trott的答案肯定是最好的。
然而,由于JS是一种动态语言,并且有如此多的JS运行时环境,instanceof操作符可能会失败,特别是在前端开发中,当跨越iframes等边界时。看到的:
https://github.com/mrdoob/three.js/issues/5886
如果你能接受鸭子输入,这应该很好:
let isError = function(e){
return e && e.stack && e.message;
}
我个人更喜欢静态类型的语言,但如果您使用的是动态语言,最好是接受动态语言的本质,而不是强迫它像静态类型的语言一样运行。
如果你想要更精确一点,你可以这样做:
let isError = (e) => {
return e && e.stack && e.message && typeof e.stack === 'string'
&& typeof e.message === 'string';
}