Coffeescript 'this' внутри jQuery .each () - PullRequest
54 голосов
/ 31 августа 2011

У меня есть какой-то код, похожий на следующий:

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 ]

128 голосов
/ 31 августа 2011

jQuery.each передает текущий элемент в качестве второго параметра обратного вызова, поэтому не имеет для резервирования this для jQuery:

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

Обратите внимание на использование жирной стрелки (=>) синтаксиса для функции обратного вызова; он связывает контекст функции с текущим значением this. (this в функции обратного вызова всегда совпадает с this в тот момент, когда вы определили функцию.)

6 голосов
/ 31 августа 2011

Вы говорите:

Использование чего-то вроде _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.

4 голосов
/ 31 августа 2011

Ваш код ...

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 функции

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...