如何从闭包内调用实例方法?

时间:2013-01-24 21:14:55

标签: coffeescript

我正在尝试访问map调用中的实例方法,遗憾的是我对实例对象的引用被重新定义为Window。我不知道如何掌握我的实例方法:

class Test
  constructor: (@an_array) ->

  f: () ->
    @an_array.map (value) ->
      @a(value)

  a: (value) ->
    alert value

t = new Test [1, 2, 3]
t.f() // TypeError: Object [object Window] has no method 'a'

Here's a functional link to the above code

2 个答案:

答案 0 :(得分:7)

有多种方法可以解决这个问题。

CoffeeScript中最常见的是使用fat arrow (=>)来生成绑定函数:

@an_array.map (value) => @a(value)

演示:http://jsfiddle.net/ambiguous/6BW8q/

标准JavaScript方法也适用(有时是必要的或更合适的):

  1. 保存对@的引用,这样您就不必关心回调函数中的this

    _this = @
    @an_array.map (value) -> _this.a(value)
    

    演示:http://jsfiddle.net/ambiguous/XhP4z/

    由于存在window.self有趣的错忘记JavaScript中的_this

  2. 使用Function.bind手动创建绑定函数,但这并不是普遍支持的:

    self

    演示:http://jsfiddle.net/ambiguous/n2XnC/

  3. 使用jQuery的$.proxy,Underscore的_.bind或其他非本地绑定函数实现:

    var

    演示:http://jsfiddle.net/ambiguous/LAy9L/

  4. 您选择哪一个取决于您的环境和特定需求:

    1. 如果您尝试绑定来自其他地方的函数,则无法使用@an_array.map ((value) -> @a(value)).bind(@) ,因此您需要使用(2)或<的某些变体strong>(3)以上(或可能Function.callFunction.apply)。
    2. 如果您同时需要内部和外部@an_array.map _((value) -> @a(value)).bind(@) ,那么您可以使用(1)
    3. 如果您需要手动绑定某个功能,但不确定原生=>是否存在,那么您可能最终会使用(3)以及的哪个分支(3)可能取决于您已有的库。
    4. ...
    5. 利润。

答案 1 :(得分:1)

通过定义一个变量来保存我对this的引用,我可以做到这一点:

class Test
  constructor: (@an_array) ->

  f: () ->
    self = @
    @an_array.map (value) ->
      self.a(value)

  a: (value) ->
    alert value

t = new Test [1, 2, 3]
t.f()  // raises 3 alerts: 1, 2, 3

Here's a working example

这感觉就像是一个黑客攻击,所以我会留下Q&amp; A给某人上学,告诉我应该怎么做。 :d