Подклассификация собственных объектов: instanceof не работает должным образом - программирование
Подтвердить что ты не робот

Подклассификация собственных объектов: instanceof не работает должным образом

Я пытаюсь подклассифицировать собственный JS Error объект в CoffeeScript для получения специализированных типов ошибок, но я обнаружил, что instanceof работает неправильно, если я не определяю конструктор в подклассах:

class SimpleError extends Error
class EmptyConstructorError extends Error
  constructor: ->
class SuperConstructorError extends Error
  constructor: -> 
    super

new SimpleError instanceof SimpleError                     # -> false
new EmptyConstructorError instanceof EmptyConstructorError # -> true
new SuperConstructorError instanceof SuperConstructorError # -> true

Проблема, по-видимому, связана с тем, как определены конструкторские функции ответил со ссылкой на коммит, где это поведение было введено, но оно не совсем объясняет, что происходит здесь, поэтому я буду попробуйте объяснить это немного, если кто-то еще задается вопросом, почему это работает таким образом.

Основная проблема - это унаследованная отвратительная "функция" из JavaScript, которая позволяет нам определить функцию-конструктор, которая возвращает объект, отличный от построенного:

function Foo() {
    return {'LOL': 'You fool!'};
}
new Foo() instanceof Foo // -> false

И есть также тот факт, что некоторые встроенные конструкторы, такие как Error, Array, String и что не нужно вызывать с помощью new: они просто вернут новый объект соответствующего введите, если вы его забудете.

В конце, добавьте эти две уродливые вещи вместе, и результат состоит в том, что вы должны запомнить class MyError extends Error then constructor: -> super вместо более интуитивного class MyError extends Error, если вы хотите, чтобы оператор instanceof работал правильно с MyError. Это потому, что неявный конструктор CoffeeScript просто вернет то, что возвращает родительский конструктор, и в этом случае сделает return Error.apply(this, arguments), который просто вернет новый объект ошибки shinny вместо объекта, который вы передали как аргумент this. Ура!

Обновление 2 (25 февраля 2013 г.)

Эта проблема была исправлена ​​в CoffeeScript 1.5.0!= D

Теперь расширение собственных объектов работает как ожидалось:

class MyError extends Error
new MyError instanceof MyError # -> true :)

Обновление 3 (Mar 04 2013)

Aaand it was on 1.6.0 = P

4b9b3361

Ответ 1

К лучшему или худшему, return был добавил в 1.3.1, чтобы исправить # 1966# 2111).