如何在 CoffeeScript 胖箭头回调中引用实际的“this”?

Posted

技术标签:

【中文标题】如何在 CoffeeScript 胖箭头回调中引用实际的“this”?【英文标题】:How do I refer to actual 'this' inside CoffeeScript fat-arrow callback? 【发布时间】:2014-02-28 14:17:40 【问题描述】:

标题说明了一切。当我在 CoffeeScript 中使用胖箭头时,它会在调用函数之前先存储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】:

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

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

第三个如下图所示。不过我不确定 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 回调范围内拥有“哪个 this”。不能同时访问两个“thises”。

顺便说一句。所有这些返回语句似乎都是不必要的。最短的工作解决方案如下所示:

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

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

【讨论】:

更多选项:(1) 旧的that = @ 技巧在 CoffeeScript 中仍然有效,(2) 即使是粗箭头,点击处理程序仍将获取作为参数传递的事件,您应该能够从该事件中提取单击的元素。 @muistooshort 你是对的。我正在考虑使用that = @ 添加第三个示例,但这与使用胖箭头相同。几乎相同,取决​​于上下文。我已经有一段时间没有使用 jQuery 了,所以没有考虑你的另一个建议。当然,您可以从作为参数 jQuery API 传递的事件中访问点击主题。 that = @=> 之间的主要区别在于that = @ 让您可以访问@s(这有点绕口令:)。我不是在批评,只是认为更多的选择更好(这是我的赞成票)。 这就是我写它几乎相同的原因。引入胖箭头是为了避免使用 that = this 技巧,这在 javascript 中是必需的。所以同时使用它和旧把戏似乎很老套。无论如何,我猜(我的第二个示例),它可能仍然比在上面定义方法回调更干净。感谢您指出这一点:) 谢谢。我想到了所有这些选择。我在问是否有另一个符号/关键字将实际的this 存储在胖箭头回调中。我知道所有这些方法。 cmets 中讨论的那个,即that = @ 是我最常使用的那个。此外,如果我使用 jQuery 并且我已经预缓存了element,则上述答案中的第 2 和第 3 方法适用,但我只是将其用作示例。我现在认为这是一个愚蠢的问题。哈哈。无论如何感谢您的帮助。

以上是关于如何在 CoffeeScript 胖箭头回调中引用实际的“this”?的主要内容,如果未能解决你的问题,请参考以下文章

CoffeeScript:如何使用胖箭头和这个?

如何将胖箭头AngularJS转换为coffeescript

如何使用咖啡脚本使用`this`和`_this`(胖箭头)?

JavaScript ES6箭头函数指南

如何配置ESLint以允许胖箭头类方法

如何使用箭头函数(公共类字段)作为类方法?