Coffeescript 计时器和“这个”;回调指针

发布于 2024-10-16 10:32:12 字数 426 浏览 0 评论 0原文

我对浏览器认为“this”的含义有疑问。在下面的示例中,在 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()

I'm having a problem with what the browser considers 'this' to be. In the following example, calling pingMe() on abc will wait 1 second and then the browser will say that Object DOMWindow has no method 'func'. Instead of resolving 'this' to the instance of class ABC (abc), it instead resolves to the DOMWindow, as if the object wasn't involved. I'm clearly not understanding how setTimeout works with respect to callback scope. Any suggestions how i can make this callback succeed?

class ABC
  @func = null

  constructor: (func) ->
    @func = func

  pingMe: ->
    setTimeout(doPing, 1000)

  doPing = ->
    @func()

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

故笙诉离歌 2024-10-23 10:32:12

我让这段代码工作了。

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。但我希望它能为您提供进一步了解的方向。

I got this code working.

class ABC
  @func = null

  constructor: (func) ->
    @func = func

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

  doPing: ->
    @func()

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

Your doPing method was defined doPing = ->, whereas the others all use name: ->, I changed it that way. pingMe uses => to create a unnamed function, and @doPing to bind this to the function.

Not sure if this is correct, I rarely use JavaScript. But I hope it might give you a direction to look further.

孤星 2024-10-23 10:32:12

另一种更接近 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,而不是设置超时

An alternative solution which is closer to what you would do in ES5 is:

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

or if you want to save on parentheses:

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

Note that bind is ES5, so only available in IE from version 9.


Also note, you should at all costs avoid the temptation to try:

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

because both of those pass the number as the second argument to bind, not setTimeout!

美煞众生 2024-10-23 10:32:12

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

class ABC
  @func = null

  constructor: (func) ->
    @func = func

  pingMe: ->
    setTimeout => @doPing, 1000

  doPing: =>
    @func()

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

Perhaps for a little more clarity, you can bind the "doPing" method instead. It'll look a bit cleaner and FWIW, I think it better expresses what you're looking to achieve.

class ABC
  @func = null

  constructor: (func) ->
    @func = func

  pingMe: ->
    setTimeout => @doPing, 1000

  doPing: =>
    @func()

abc = new ABC ->
  alert "HI"
abc.pingMe()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文