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

Gav*_*ler 4 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'
Run Code Online (Sandbox Code Playgroud)

这是上述代码的功能链接

mu *_*ort 7

有各种方法可以解决这个问题.

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

@an_array.map (value) => @a(value)
Run Code Online (Sandbox Code Playgroud)

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

标准的JavaScript方法也可以工作(有时是必要的或更合适的):

  1. 保存引用,@以便您不必关心this回调函数内部的内容:

    _this = @
    @an_array.map (value) -> _this.a(value)
    
    Run Code Online (Sandbox Code Playgroud)

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

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

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

    @an_array.map ((value) -> @a(value)).bind(@)
    
    Run Code Online (Sandbox Code Playgroud)

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

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

    @an_array.map _((value) -> @a(value)).bind(@)
    
    Run Code Online (Sandbox Code Playgroud)

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

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

  1. 如果你试图绑定来自其他地方的函数,那么就不能使用,=>所以你需要使用上面(2)(3)的某些变体(或者可能Function.call或者Function.apply).
  2. 如果你同时需要内部和外部this,那么你可以选择(1).
  3. 如果您需要手动绑定功能,但你不知道,本地bind存在,那么你"可能与最终(3)和分支(3)可能将取决于哪个库您已经拥有.
  4. ...
  5. 利润.