在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'))
}

其他回答

你可以使用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"。错误实例没有特殊属性。

你可以使用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”的属性

打印稿的解决方案

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

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

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);
}

你可以进一步从@iota得到答案,并通过getPrototypeOf()或已弃用的__proto__属性检查测试对象的内部[[Prototype]]属性。

如果对象是一个错误,它继承自error .prototype。也许是这样的:

// the object you want to check 
const objectToCheck = new Error();

// current way
console.log(Object.getPrototypeOf(objectToCheck) === Error.prototype);  /* true*/

// deprecated way
console.log(objectToCheck.__proto__ === Error.prototype);  /* true */

对于那些正在寻找某种“官方”方式的人(就像我一样),这是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
  }
}