Coffeescript'this'在jQuery .each()中

54 javascript coffeescript

我有一些像以下一样的咖啡因:

class foo:
    @bar = 'bob loblaw'

    processRows: ->
        $("#my-table>tr").each ->
            id = $(this).attr("id")
            @processRow id

    processRow: (id) ->
        console.log @bar + id
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:我需要this引用.each循环内部的上下文来获取id,但我也想this引用里面的类实例foo.processRow()---它目前没有.

使用函数_this = this外部的东西.each并传递它也不是一个很好的解决方案,因为我在里面引用了很多类变量processRow.

有什么想法吗?我错过了一些明显的东西吗 谢谢!

Arn*_*anc 128

jQuery.each通过当前元素作为回调的第二个参数,所以你不要保留this的jQuery:

processRows: ->
    $("#my-table>tr").each (index, element) =>
        id = $(element).attr("id")
        @processRow id
Run Code Online (Sandbox Code Playgroud)

注意回调函数使用fat arrow(=>)语法 ; 它将函数的上下文绑定到当前的值this.(this在回调函数中始终与this定义函数时的函数相同.)

  • **胖箭头语法**为我做了诀窍!只是想为那些看着这个的人再次突出它. (7认同)

Tre*_*ham 6

你说

使用函数_this = this外部的东西.each并传递它也不是一个很好的解决方案,因为我在processRow中引用了许多类变量.

不过,这是最有效的解决方案.JavaScript this是一个奇怪的野兽; 您可以使用=>运算符将其固定在嵌套函数内部,因为arnaud576875在他的答案中提取(这是优雅但效率低下),或者您可以复制this到另一个变量(这是有效但不优雅的).这是你的选择.

请注意,一些现代浏览器支持bind每个函数的方法,这比CoffeeScript更有效=>.有一个打开的票,可以在可用时=>使用本机bind:https://github.com/jashkenas/coffee-script/pull/1408

附录:当然,比上述任何一种更有效的替代方案是写作

for element, index in $('#my-table>tr')
  ...
Run Code Online (Sandbox Code Playgroud)

这也可以解决你的this问题.

  • @tothemario对,在'for`循环中没有作用域,但是提问者的原始示例并没有涉及任何嵌套函数,因此`for ... in`是一个非常好的解决方案(并且,如上所述,更有效) .如果有数百个`tr`,那么不必要的函数调用的开销可能会很明显. (2认同)

Ric*_*ick 5

你的代码...

class foo
    @bar = 'bob loblaw'

    processRows: ->
        $("#my-table>tr").each ->
            id = $(this).attr("id")
            @processRow id

    processRow: (id) ->
        console.log @bar + id
Run Code Online (Sandbox Code Playgroud)

被转译为...

var foo;
foo = (function() {
  function foo() {}
  foo.bar = 'bob loblaw';
  foo.prototype.processRows = function() {
    return $("#my-table>tr").each(function() {
      var id;
      id = $(this).attr("id");
      return this.processRow(id);
    });
  };
  foo.prototype.processRow = function(id) {
    return console.log(this.bar + id);
  };
  return foo;
})();
Run Code Online (Sandbox Code Playgroud)

这对它正在翻译的当前上下文做了很多假设。不幸的是,由于 jQuery 管理上下文,因此您必须明确或声明对类的this.

顺便说一下,生成的代码还有其他问题,看看这个简化的案例:

class foo
    @bar = 'bob loblaw'

    getBar: () ->
        @bar
Run Code Online (Sandbox Code Playgroud)

转译为:

var foo;
foo = (function() {
  function foo() {}
  foo.bar = 'bob loblaw';
  foo.prototype.getBar = function() {
    return this.bar;
  };
  return foo;
})();
Run Code Online (Sandbox Code Playgroud)

尝试使用这段代码的结果:

> foo.bar;
"bob loblaw"

> var f = new foo();
undefined

> f.getBar();
undefined
Run Code Online (Sandbox Code Playgroud)

您的代码似乎期望这@bar是一个自己的属性,但它被创建为foo函数的静态属性