6

我对浏览器认为“this”的内容有疑问。在以下示例中,在 abc 上调用 pingMe() 将等待 1 秒,然后浏览器会说 Object DOMWindow has no method '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()
4

3 回答 3

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用于=>创建一个未命名的函数,并@doPing绑定this到该函数。

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

于 2011-02-07T02:27:33.550 回答
1

一个更接近于您在 ES5 中所做的替代解决方案是:

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

或者如果你想保存括号:

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

请注意,这bind是 ES5,因此仅在 IE 版本 9 中可用。


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

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

因为这两个都将数字作为第二个参数传递给bind, not setTimeout!

于 2014-06-20T07:59:23.797 回答
0

也许为了更清楚一点,您可以绑定“doPing”方法。它看起来会更干净和 FWIW,我认为它更好地表达了你想要实现的目标。

class ABC
  @func = null

  constructor: (func) ->
    @func = func

  pingMe: ->
    setTimeout => @doPing, 1000

  doPing: =>
    @func()

abc = new ABC ->
  alert "HI"
abc.pingMe()
于 2012-02-03T15:07:47.070 回答