Coffeescript: 'this' внутри jQuery .each()
У меня есть код на 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.
Есть ли у кого-то идеи? Может, я упустил что-то очевидное? Спасибо!
2 ответ(ов)
Вы говорите:
Использовать что-то вроде
_this = thisвне функции.eachи передавать его вокруг — не лучшее решение, поскольку я ссылаюсь на множество переменных класса внутриprocessRow.
На самом деле, это наиболее эффективное решение. this в JavaScript — странная штука; вы можете зафиксировать его внутри вложенной функции, используя оператор =>, как предлагает arnaud576875 в своем ответе (это элегантно, но неэффективно), или скопировать this в другую переменную (что эффективно, но не элегантно). Какой путь выбрать — решать вам.
Обратите внимание, что некоторые современные браузеры поддерживают метод bind для каждой функции, который более эффективен, чем => в CoffeeScript. Существует открытый тикет для того, чтобы => использовал нативный bind, когда он доступен: https://github.com/jashkenas/coffee-script/pull/1408
Дополнение: Конечно, более эффективной альтернативой любому из вышеперечисленных решений будет запись:
for (element, index) in $('#my-table>tr')
...
что также решит вашу проблему с this.
Ваш код...
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.
Где найти документацию по форматированию даты в JavaScript?
Как определить нажатие клавиши Esc?
Как проверить, содержит ли массив строку в TypeScript?
Ссылка и выполнение внешнего JavaScript-файла, размещенного на GitHub
Как остановить Babel от трансформации 'this' в 'undefined' и добавления "use strict"