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


当前回答

或者对不同类型的错误使用这个

function isError(val) {
  return (!!val && typeof val === 'object')
    && ((Object.prototype.toString.call(val) === '[object Error]')
      || (typeof val.message === 'string' && typeof val.name === 'string'))
}

其他回答

感谢@Trott的代码,我只是使用了相同的代码,并添加了一个实时工作的示例,以造福他人。

<html> <body > <p>The **instanceof** operator returns true if the specified object is an instance of the specified object.</p> <script> var myError = new Error("TypeError: Cannot set property 'innerHTML' of null"); // error type when element is not defined myError instanceof Error // true function test(){ var v1 = document.getElementById("myid").innerHTML ="zunu"; // to change with this try { var v1 = document.getElementById("myidd").innerHTML ="zunu"; // exception caught } catch (e) { if (e instanceof Error) { console.error(e.name + ': ' + e.message) // error will be displayed at browser console } } finally{ var v1 = document.getElementById("myid").innerHTML ="Text Changed to Zunu"; // finally innerHTML changed to this. } } </script> <p id="myid">This text will change</p> <input type="button" onclick="test();"> </body> </html>

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

你可以使用obj.constructor.name检查对象https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#Function_names_in_classes的“类”

例如

var error = new Error("ValidationError");
console.log(error.constructor.name);

上面的行将记录“Error”,这是对象的类名。这可以用于javascript中的任何类,如果类没有使用名称为“name”的属性

只需使用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') }

打印稿的解决方案

可以定义用户定义的类型保护,只需要定义一个返回类型为类型谓词的函数

你可以像这样检查一个变量是否有错误

const isError = (err: unknown): err is Error => err instanceof Error;

然后在try catch中像这样验证它

try {
  login(username, password);
} catch (err) {
  if (isError(err)) {
  console.log(err.message);
}