Подтвердить что ты не робот

Проверка ошибки typeof в JS

В 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 какой-либо помощи?

4b9b3361

Ответ 1

Вы можете использовать оператор instanceof.

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

Ответ 2

Я задал оригинальный вопрос - ответ @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 = function(e){
     return e && e.stack && e.message && typeof e.stack === 'string' 
            && typeof e.message === 'string';
    }

Ответ 3

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

Ответ 4

Или используйте это для разных типов ошибок

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

Ответ 5

Вы можете использовать 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);

В приведенной выше строке будет записано "Ошибка", которая является именем класса объекта. Это может быть использовано с любыми классами в javascript, если класс не использует свойство, которое называется "имя"