Coffeescript'this'在jQuery .each()中

时间:2011-08-31 18:15:14

标签: javascript coffeescript

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

class foo:
    @bar = 'bob loblaw'

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

    processRow: (id) ->
        console.log @bar + id

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

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

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

3 个答案:

答案 0 :(得分:128)

jQuery.each将当前元素作为回调的第二个参数传递,因此您不 为jQuery保留this

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

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

答案 1 :(得分: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')
  ...

这也可以解决您的this问题。

答案 2 :(得分:4)

您的代码......

class foo
    @bar = 'bob loblaw'

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

    processRow: (id) ->
        console.log @bar + id

被转化为......

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;
})();

关于它正在转化的当前背景,它已经假设了很多。不幸的是,由于jQuery管理上下文,你必须明确或声明对你的类this的引用。

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

class foo
    @bar = 'bob loblaw'

    getBar: () ->
        @bar

透明至:

var foo;
foo = (function() {
  function foo() {}
  foo.bar = 'bob loblaw';
  foo.prototype.getBar = function() {
    return this.bar;
  };
  return foo;
})();

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

> foo.bar;
"bob loblaw"

> var f = new foo();
undefined

> f.getBar();
undefined

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