Coffeescript计时器和'this'指针回调

时间:2011-02-07 01:59:33

标签: coffeescript

我遇到浏览器认为“这个”的问题。在下面的示例中,在abc上调用pingMe()将等待1秒,然后浏览器将说Object DOMWindow没有方法'func'。它不是将'this'解析为类ABC(abc)的实例,而是解析为DOMWindow,就好像没有涉及对象一样。我显然不理解setTimeout如何处理回调范围。我有什么建议可以让这个回调成功吗?

class ABC
  @func = null

  constructor: (func) ->
    @func = func

  pingMe: ->
    setTimeout(doPing, 1000)

  doPing = ->
    @func()

abc = new ABC ->
  alert "HI"
abc.pingMe()

3 个答案:

答案 0 :(得分:10)

我让这段代码正常工作。

class ABC
  @func = null

  constructor: (func) ->
    @func = func

  pingMe: ->
    setTimeout =>
     @doPing()
    , 1000

  doPing: ->
    @func()

abc = new ABC ->
  alert "HI"
abc.pingMe()

您的doPing方法已定义doPing = ->,而其他人都使用name: ->,我改变了这种方式。 pingMe使用=>创建一个未命名的函数,@doPingthis绑定到该函数。

不确定这是否正确,我很少使用JavaScript。但我希望它可以给你一个进一步观察的方向。

答案 1 :(得分:1)

更接近你在ES5中所做的另一种解决方案是:

pingMe: ->
    setTimeout(@doPing.bind(@), 1000)

或者如果你想保存在括号上:

pingMe: ->
    setTimeout (@doPing.bind @), 1000

请注意,bind是ES5,因此在版本9的IE中只有available


另请注意,您应该不惜一切代价 避免 尝试尝试:

    setTimeout(@doPing.bind @, 1000)    # BAD!
       or
    setTimeout @doPing.bind @, 1000     # BAD!

因为这两个都将数字作为第二个参数传递给bind,而不是setTimeout

答案 2 :(得分:0)

也许为了更清晰一点,你可以绑定" doPing"方法而不是。它看起来有点清洁和FWIW,我认为它更好地表达了你想要实现的目标。

class ABC
  @func = null

  constructor: (func) ->
    @func = func

  pingMe: ->
    setTimeout => @doPing, 1000

  doPing: =>
    @func()

abc = new ABC ->
  alert "HI"
abc.pingMe()