【问题标题】:How to call an instance method from inside a closure?如何从闭包内部调用实例方法?
【发布时间】:2015-09-24 03:09:15
【问题描述】:

我正在尝试访问 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

【问题讨论】:

    标签: coffeescript


    【解决方案1】:

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

    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/

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

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

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

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

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

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

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

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

    1. 如果您尝试绑定来自其他地方的函数,则不能使用 =>,因此您需要使用 (2) 的一些变体(3) 上面(或者可能是Function.callFunction.apply)。
    2. 如果您同时需要内部和外部this,那么您会选择(1)
    3. 如果您需要手动绑定一个函数,但不确定是否存在原生 bind,那么您可能会得到 (3) 以及 (3 的哪个分支) 可能取决于您已经拥有的库。
    4. ...
    5. 利润。

    【讨论】:

      【解决方案2】:

      发现我可以通过定义一个变量来保存我对 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.

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

      【讨论】:

      • @muistooshort 您应该回答这个问题,我会将其标记为已接受。这就是我要找的东西!
      • 或者我们可以将其作为副本删除,我想我已经回答了这个more than a few times。如果您解决了问题,我很高兴。
      • @muistooshort 我已经使用 SO 一段时间了,但我找不到答案...如果我们离开它可能会帮助某人。
      • 我为后人添加了一个答案,这种东西很难搜索,您可能会注意到我搜索的是我已经知道的答案而不是问题:)
      猜你喜欢
      • 1970-01-01
      • 2016-08-30
      • 2013-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多