Subclassificando objetos nativos: instanceof não funcionando corretamente

Eu estou tentando subclasse o JS nativoError objeto no CoffeeScript para obter tipos de erros especializados, mas eu achei que oinstanceof não funciona corretamente se eu não definir um construtor nas subclasses:

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

O problema parece ser causado por como oJS gerado funções construtoras são definidas. Quando eunão faça define um construtor no CoffeeScript:

SimpleError = (function(_super) {

  __extends(SimpleError, _super);

  function SimpleError() {
    return SimpleError.__super__.constructor.apply(this, arguments);
  }

  return SimpleError;

})(Error);

E quando euFaz define um construtor no CoffeeScript:

SuperConstructorError = (function(_super) {

  __extends(SuperConstructorError, _super);

  function SuperConstructorError() {
    SuperConstructorError.__super__.constructor.apply(this, arguments);
  }

  return SuperConstructorError;

})(Error);

Como você pode ver, a diferença é simplesreturn no primeiro caso. Eu não entendo porque isso faz alguma diferença noinstanceof comportamento, porém, como o super construtor está apenas sendo aplicado aothis objeto (ou seja, o super construtor não está sendo chamado comnew), mas, novamente, eu não entendo muito como os construtores JS trabalham = P

E o mais estranho é que esse comportamento parece acontecer apenas ao criar subclasses de objetos JS nativos. Se eu subclasse classes CoffeeScript, tudo funciona como esperado.

Alguma idéia de por que isso pode estar acontecendo e como eu poderia evitar escrever construtores falsos apenas para oinstanceof operador para funcionar corretamente?

Obrigado!

Atualizar

Então o usuário matyrrespondidas com um link para o commit onde este comportamento foi introduzido, mas isso não explica exatamente o que está acontecendo aqui, então eu tentarei explicar isso um pouco caso alguém mais se pergunte por que isso funciona dessa maneira.

O principal problema é esse "recurso" desagradável herdado do JavaScript que nos permite definir uma função construtora que retorna um objeto diferente daquele que está sendo construído:

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

E há também o fato de que alguns construtores nativos, comoError, Array, String e não precisa ser chamado comnew: eles apenas retornarão um novo objeto do tipo correspondente se você o esquecer.

No final, adicione essas duas coisas feias juntas e o resultado é que você deve se lembrar de escreverclass MyError extends Error then constructor: -> super em vez do mais intuitivoclass MyError extends Error se você quiserinstanceof operador para trabalhar corretamente comMyError. Isso porque o construtor implícito do CoffeeScript retornará apenas o que o construtor pai devolver e, nesse caso, faráreturn Error.apply(this, arguments) que apenas retornará um novo objeto de erro em vez do objeto que você passou como othis argumento. Yay!

Atualização 2 (25 de fevereiro de 2013)

Este problemafoi corrigido no CoffeeScript 1.5.0! = D

Agora, estender objetos nativos funciona conforme o esperado:

class MyError extends Error
new MyError instanceof MyError # -> true :)
Atualização 3 (04 de março de 2013)

Aaand ele foi em 1.6.0 = P

questionAnswers(1)

yourAnswerToTheQuestion