Subclasificar objetos nativos: instanceof no funciona correctamente

Estoy tratando de subclasificar el JS nativoError objeto en CoffeeScript para obtener tipos de error especializados, pero encontré que elinstanceof no funciona correctamente si no defino un constructor en las subclases:

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

El problema parece ser causado por cómo elJS generado Se definen funciones constructoras. Cuando yono hacer Definir un constructor en CoffeeScript:

SimpleError = (function(_super) {

  __extends(SimpleError, _super);

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

  return SimpleError;

})(Error);

Y cuando yohacer Definir un constructor en CoffeeScript:

SuperConstructorError = (function(_super) {

  __extends(SuperConstructorError, _super);

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

  return SuperConstructorError;

})(Error);

Como puedes ver, la diferencia es un simplereturn en el primer caso. No entiendo por qué esto hace alguna diferencia en elinstanceof comportamiento, sin embargo, como el súper constructor se está aplicando a lathis objeto (es decir, el súper constructor no está siendo llamado connew), pero tampoco entiendo mucho cómo funcionan los constructores JS = P

Y lo extraño es que este comportamiento parece ocurrir solo cuando se subclasifican objetos JS nativos. Si subclasifico en las clases de CoffeeScript, todo funciona como se espera.

Cualquier idea de por qué esto podría estar sucediendo y cómo podría evitar escribir constructores ficticios solo para elinstanceof operador para trabajar correctamente?

¡Gracias!

Actualizar

Así que el usuario matyrcontestado con un enlace a la confirmación donde se introdujo este comportamiento, pero no explica exactamente lo que está sucediendo aquí, así que intentaré explicarlo un poco en caso de que alguien más se pregunte por qué esto funciona de esta manera.

El principal problema es esta "característica" desagradable heredada de JavaScript que nos permite definir una función constructora que devuelve un objeto distinto al que se está construyendo:

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

Y también está el hecho de que algunos constructores nativos, comoError, Array, String y todo eso no necesita ser llamado connew: solo devolverán un nuevo objeto del tipo correspondiente si lo olvidas.

Al final, agregue estas dos cosas feas juntas y el resultado es que debe recordar escribirclass MyError extends Error then constructor: -> super en lugar de lo más intuitivoclass MyError extends Error si quieres elinstanceof operador para trabajar correctamente conMyError. Esto se debe a que el constructor implícito de CoffeeScript simplemente devolverá lo que devuelva el constructor principal, y en este caso lo haráreturn Error.apply(this, arguments) que simplemente devolverá un nuevo objeto de error brillante en lugar del objeto que pasó como elthis argumento. ¡Hurra!

Actualización 2 (25 de febrero de 2013)

Este problemafue arreglado en CoffeeScript 1.5.0! = D

Ahora la extensión de los objetos nativos funciona como se espera:

class MyError extends Error
new MyError instanceof MyError # -> true :)
Actualización 3 (04 de marzo de 2013)

Aaand se ha ido en 1.6.0 = P

Respuestas a la pregunta(1)

Su respuesta a la pregunta