4

我试图在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'

这是上述代码的功能链接

4

2 回答 2

7

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

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

@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/

    我倾向于使用_this而不是self作为这个东西的名称,因为如果你忘记了JavaScript中的存在window.self有趣的错误会导致它的存在。var

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

    @an_array.map ((value) -> @a(value)).bind(@)
    

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

  3. 使用 jQuery's $.proxy、 Underscore's_.bind或其他一些非本地绑定函数实现:

    @an_array.map _((value) -> @a(value)).bind(@)
    

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

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

  1. 如果您尝试绑定来自其他地方的函数,那么您将无法使用=>,因此您需要使用上述(2)(3)的一些变体(或者可能是Function.callor Function.apply)。
  2. 如果您同时需要内部和外部this,那么您将使用(1)
  3. 如果您需要手动绑定一个函数,但您不确定是否bind存在原生函数,那么您可能会以 (3) 结尾,而( 3 )的哪个分支可能取决于您已经拥有的库。
  4. ...
  5. 利润。
于 2013-01-25T00:44:04.857 回答
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

这是一个工作示例

这感觉有点像 hack,所以我会把 Q&A 留给别人来教我应该如何做。:D

于 2013-01-24T21:17:35.810 回答