2011-02-07 38 views
6

我对浏览器认为'this'有问题。在以下示例中,调用abc上的pingMe()将等待1秒,然后浏览器会说Object DOMWindow没有方法'func'。而不是将ABC解析为类(ABC)的实例,而是解析为DOMWindow,就好像该对象没有涉及。我显然不理解setTimeout如何处理回调范围。任何建议如何使这个回调成功?Coffeescript定时器和回调上的'this'指针

class ABC 
    @func = null 

    constructor: (func) -> 
    @func = func 

    pingMe: -> 
    setTimeout(doPing, 1000) 

    doPing = -> 
    @func() 

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

hm,将setTimeout行改为`obj = this; setTimeout(( - > obj.doPing()),1000)`doPing声明为`doPing: - >`似乎修复它。看起来CoffeeScript在这些场景中保持常规的JavaScript行为。 – Larry 2011-02-07 02:24:51

回答

10

我得到了这段代码的工作。

class ABC 
    @func = null 

    constructor: (func) -> 
    @func = func 

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

    doPing: -> 
    @func() 

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

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

不知道这是否正确,我很少使用JavaScript。但我希望这可能会给你一个看得更远的方向。

+0

是的,就是这样。我缺乏`=>`的知识。 – Larry 2011-02-07 03:25:48

0

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

class ABC 
    @func = null 

    constructor: (func) -> 
    @func = func 

    pingMe: -> 
    setTimeout => @doPing, 1000 

    doPing: => 
    @func() 

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

我认为应该是`=> @doPing()`。 `=> @ doPing`计算返回绑定函数的函数,而不是调用绑定函数的函数。见赖纳的答案。 – joeytwiddle 2014-06-20 07:35:53

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