我遇到浏览器认为“这个”的问题。在下面的示例中,在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()
答案 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
使用=>
创建一个未命名的函数,@doPing
将this
绑定到该函数。
不确定这是否正确,我很少使用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()