首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >本机对象的子类化: instanceof不能正常工作

本机对象的子类化: instanceof不能正常工作
EN

Stack Overflow用户
提问于 2012-05-30 03:02:30
回答 1查看 3K关注 0票数 17

我尝试在CoffeeScript中将原生JS Error对象子类化,以获得专门的错误类型,但我发现如果不在子类中定义构造函数,instanceof将无法正常工作:

代码语言:javascript
复制
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中定义构造函数时:

代码语言:javascript
复制
SimpleError = (function(_super) {

  __extends(SimpleError, _super);

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

  return SimpleError;

})(Error);

当我在CoffeeScript中定义构造函数时:

代码语言:javascript
复制
SuperConstructorError = (function(_super) {

  __extends(SuperConstructorError, _super);

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

  return SuperConstructorError;

})(Error);

如您所见,第一种情况下的区别是一个简单的return。我不明白为什么这会对instanceof行为有任何影响,因为超级构造函数只是应用于this对象(即超级构造函数不是用new调用的),但话又说回来,我不太理解JS构造函数是如何工作的=P

奇怪的是,这种行为似乎只在本机JS对象的子类化时发生。如果我子类化CoffeeScript类,一切都像预期的那样工作。

你知道为什么会发生这种情况吗?为了让instanceof操作符正常工作,我该如何避免编写伪构造函数呢?

谢谢!

更新

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

主要的问题是从JavaScript继承的这个讨厌的“特性”,它让我们定义一个构造函数,返回一个不同于正在构造的对象的对象:

代码语言:javascript
复制
function Foo() {
    return {'LOL': 'You fool!'};
}
new Foo() instanceof Foo // -> false

还有一个事实是,一些本机构造函数,如ErrorArrayString等不需要用new调用:如果您碰巧忘记了,它们只会返回相应类型的新对象。

最后,将这两个丑陋的东西加在一起,结果是,如果您想让class MyError extends Error then constructor: -> super操作符正确地与class MyError extends Error一起工作,那么您应该记住编写instanceof而不是更直观的MyError。这是因为CoffeeScript的隐式构造函数将只返回父构造函数返回的任何内容,在本例中将执行return Error.apply(this, arguments),它将只返回一个闪亮的新错误对象,而不是您作为this参数传递的对象。耶!

更新2(2013年2月25日)

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

现在,扩展本机对象的工作方式与预期一致:

代码语言:javascript
复制
class MyError extends Error
new MyError instanceof MyError # -> true :)

更新3(2013年3月4日)

它在1.6.0 =P上消失了

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-05-30 06:58:12

不管是好是坏,return在1.3.1上是added,以修复#1966 (和#2111)。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10805084

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档