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"