我如何在CoffeeScript fat-arrow回调中引用实际的'this'?

时间:2014-02-04 14:40:19

标签: syntax coffeescript scope this arrow-functions

标题说明了一切。当我在CoffeeScript中使用fat-arrow时,它会在调用函数之前先存储this。例如:

class myClass
    constructor: ->
        element = $ "#id"
        element.click ->
            @myMethod(@value)
            return
        return

    myMethod: (c)->
        window.console.log(c)
        return

会产生

var myClass;

myClass = (function() {
  function myClass() {
    var element;
    element = $("#id");
    element.click(function() {
      this.myMethod(this.value);
    });
    return;
  }

  myClass.prototype.myMethod = function(c) {
    window.console.log(c);
  };

  return myClass;

})();

现在在JavaScript第8行,this.myMethod是错误的。在此范围内,this引用element而不是类MyClass

但是,如果在CoffeeScript的第4行,我将element.click ->替换为element.click =>,则JavaScript中的第8行将变为_this.myMethod(_this.val),其中存储了引用myClass的this在调用函数之前在_this中。但_this.value未定义,即使已定义,我在此处尝试访问的对象是element(在此函数范围内由实际的this关键字引用)

现在如何访问实际的this

1 个答案:

答案 0 :(得分:2)

您至少可以通过三种方式实现目标。第一个是:

class myClass
    constructor: ->
        element = $ "#id"
        element.click =>
            @myMethod(element.value)
            return
        return

    myMethod: (c) ->
        window.console.log(c)
        return

第二名:

class myClass
    constructor: ->
        element = $ "#id"
        myMethodCallback = (c) => @myMethod(c)
        element.click ->
            myMethodCallback(@value)
            return
        return

    myMethod: (c) ->
        window.console.log(c)
        return

第3个如下所示。我不确定jQuery API的用法,所以最好检查一下appropriate docs page

class myClass
    constructor: ->
        element = $ "#id"
        element.click (event) =>
            @myMethod(event.target.value)
            return
        return

    myMethod: (c) ->
        window.console.log(c)
        return

我更喜欢第一种方式,因为它似乎更直接。 这个或另一个,但你需要在element.click回调的范围内决定你想要的“这个”。不可能同时访问两个'thises'。

顺便说一下。所有这些退货声明似乎都没有必最短的工作解决方案如下:

class myClass
    constructor: ->
        element = $ "#id"
        element.click => @myMethod(element.value)

    myMethod: (c) -> window.console.log(c)