为什么这会编译对类的引用而不是实例?

时间:2013-10-26 19:33:18

标签: javascript coffeescript

class Foo 
  bar: "hello"
  biz:
    bang: ()=> alert @bar
foo = new Foo()

编译到

var Foo, foo;

Foo = (function() {
  var _this = this;

  function Foo() {}

  Foo.prototype.bar = 'hello';

  Foo.prototype.biz = {
    bang: function() {
      return alert(Foo.bar);
    }
  };

  return Foo;

}).call(this);

foo = new Foo();

主要是为什么这会编译为alert(Foo.bar);而不是对实例的引用?

2 个答案:

答案 0 :(得分:2)

它使用=>代替->来编译对类的引用。 =>将函数的@绑定到函数外部的@。对于类函数,@函数的外bang是类本身。

使用->意味着您的函数中的@取决于函数的调用方式,因此调用instance.biz.bang()将导致alert(biz.bar)。像你一样尝试嵌套对象通常会令人困惑。你有没有理由这样做?我说这里的正确答案是不要像你一样窝,或者在任何地方明确地做instance.biz.bang.call(instance),这将是非常难看的。

答案 1 :(得分:1)

您可以根据需要命名方法,只需在正确的位置执行,以便@符合您的预期。例如:

class Foo 
  bar: "hello"
  constructor: ->
    @biz =
      bang: => console.log @bar
foo = new Foo
foo.biz.bang() # 'Hello' in the console.
f = foo.biz.bang
f()            # Also 'Hello' in the console.

Demo

请注意,必须在构造函数中使用bang: => ...,以确保@符合您在bang内的预期。