在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操作符有什么帮助吗?


当前回答

您可以使用instanceof操作符(但请参阅下面的警告!)。

var myError = new Error('foo');
myError instanceof Error // true
var myString = "Whatever";
myString instanceof Error // false

如果在不同的窗口/帧/iframe中抛出错误,而不是在检查发生的地方,上述操作将不起作用。在这种情况下,instanceof Error检查将返回false,即使对于Error对象也是如此。在这种情况下,最简单的方法是鸭子类型。

if (myError && myError.stack && myError.message) {
  // it's an error, probably
}

但是,如果您拥有包含堆栈和消息属性的非错误对象,那么duck-typing可能会产生误报。

其他回答

对于那些正在寻找某种“官方”方式的人(就像我一样),这是MDN推荐的:

try {
  myRoutine();
} catch (e) {
  if (e instanceof RangeError) {
    // statements to handle this very common expected error
  } else {
    throw e;  // re-throw the error unchanged
  }
}

您可以使用instanceof操作符(但请参阅下面的警告!)。

var myError = new Error('foo');
myError instanceof Error // true
var myString = "Whatever";
myString instanceof Error // false

如果在不同的窗口/帧/iframe中抛出错误,而不是在检查发生的地方,上述操作将不起作用。在这种情况下,instanceof Error检查将返回false,即使对于Error对象也是如此。在这种情况下,最简单的方法是鸭子类型。

if (myError && myError.stack && myError.message) {
  // it's an error, probably
}

但是,如果您拥有包含堆栈和消息属性的非错误对象,那么duck-typing可能会产生误报。

我问了最初的问题——@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';
    }

只需使用error.name

函数_err(type = false) { 如果(类型){ 抛出新的TypeError('哦,糟糕!') } 抛出新的错误('哦,糟糕!') } 尝试{ _err(真正的) } catch(错误){ console.log(typeof error.name, error.name, error.name === 'TypeError') } 尝试{ _err () } catch(错误){ console.log(typeof Error .name, Error .name, Error .name === 'Error') }

var myError = new Error('foo');
myError instanceof Error // true
var myString = "Whatever";
myString instanceof Error // false

唯一的问题是

myError instanceof Object // true

另一种方法是使用构造函数属性。

myError.constructor === Object // false
myError.constructor === String // false
myError.constructor === Boolean // false
myError.constructor === Symbol // false
myError.constructor === Function // false
myError.constructor === Error // true

尽管需要注意的是,这种匹配是非常具体的,例如:

myError.constructor === TypeError // false