coffeescript - 子类化 native 对象 : instanceof not working properly

标签 coffeescript

我正在尝试继承原生 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

该问题似乎是由 generated JS定义了构造函数。当我没有在 CoffeeScript 中定义构造函数时:
SimpleError = (function(_super) {

  __extends(SimpleError, _super);

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

  return SimpleError;

})(Error);

当我在 CoffeeScript 中定义一个构造函数时:
SuperConstructorError = (function(_super) {

  __extends(SuperConstructorError, _super);

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

  return SuperConstructorError;

})(Error);

如您所见,区别很简单 return在第一种情况下。我不明白为什么这会对 instanceof 产生任何影响。但是行为,因为 super 构造函数只是被应用于 this对象(即没有使用 new 调用 super 构造函数),但是我又不明白 JS 构造函数的工作原理 =P

奇怪的是,这种行为似乎只发生在对原生 JS 对象进行子类化时。如果我将 CoffeeScript 类子类化,一切都会按预期工作。

知道为什么会发生这种情况以及我如何避免仅为 instanceof 编写虚拟构造函数运算符(operator)正常工作?

谢谢!

更新

所以用户 matyr answered带有一个指向引入此行为的提交的链接,但它并不能完全解释这里发生了什么,所以我将尝试解释一下,以防其他人想知道为什么会这样工作。

主要问题是这个从 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运算符(operator)与 MyError 正常工作.这是因为 CoffeeScript 的隐式构造函数只会返回父构造函数返回的任何内容,在这种情况下会执行 return Error.apply(this, arguments)它只会返回一个 Shiny 的新错误对象,而不是您作为 this 传递的对象争论。耶!

更新 2(2013 年 2 月 25 日)

这个问题was fixed in CoffeeScript 1.5.0 ! =D

现在扩展 native 对象按预期工作:
class MyError extends Error
new MyError instanceof MyError # -> true :)

更新 3(2013 年 3 月 4 日)

Aaand 它已经在 1.6.0 =P

最佳答案

无论好坏,returnadded在 1.3.1 上修复 #1966 (和 #2111 )。

关于coffeescript - 子类化 native 对象 : instanceof not working properly,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10805084/

相关文章:

javascript - Rails Table - 动态条件字体格式

使用 RequireJS 优化器 r.js 缩小后,Jquery 对象转换为普通变量

javascript - Marionette ItemView 未发出 "change"事件

javascript - 我可以使用 rx.js 观察数组的添加吗?

javascript - 为什么我想运行 Coffeescript cake 命令时却运行了 CakePHP 的 cake 命令?

json - 在rails中使用CoffeScript检索json数据

javascript - 将javascript中的字符串更改为对象

javascript - 是什么导致了这个范围内的polyfill出现这种奇怪的行为?

ruby-on-rails - Coffeescript/Rails 中的范围

javascript - 如何向 Ember.js 对象添加动态方法名称?