J'ai quelques scripts comme celui-ci:
class foo:
@bar = 'bob loblaw'
processRows: ->
$("#my-table>tr").each ->
id = $(this).attr("id")
@processRow id
processRow: (id) ->
console.log @bar + id
Donc mon problème est: j'ai besoin de this
pour référencer le contexte .each
À l'intérieur de la boucle pour arriver à id
, mais je voudrais aussi que this
fasse référence à la instance de classe à l'intérieur de foo.processRow()
--- ce qu'elle ne fait pas actuellement.
Utiliser quelque chose comme _this = this
En dehors de la fonction .each
Et le faire circuler n'est pas non plus une excellente solution, car je référence de nombreuses variables de classe dans processRow
.
Des pensées? Suis-je en train de manquer quelque chose d'évident? Merci!
jQuery.each
passe l'élément courant comme deuxième paramètre du rappel, donc vous n'avez pas ayez à réserver this
pour jQuery:
processRows: ->
$("#my-table>tr").each (index, element) =>
id = $(element).attr("id")
@processRow id
Remarquez l'utilisation du grosse flèche (=>
) syntaxe pour la fonction de rappel; il lie le contexte de la fonction à la valeur actuelle de this
. (this
dans la fonction de rappel est toujours le même this
que celui au moment où vous avez défini la fonction.)
Vous dites
Utiliser quelque chose comme
_this = this
En dehors de la fonction.each
Et le faire circuler n'est pas non plus une excellente solution, car je référence de nombreuses variables de classe à l'intérieur de processRow.
C'est cependant la solution la plus efficace. this
de JavaScript est une bête étrange; vous pouvez le garder fixe à l'intérieur d'une fonction imbriquée en utilisant l'opérateur =>
, comme le suggère arnaud576875 dans sa réponse (qui est élégante mais inefficace), ou vous pouvez copier this
dans une autre variable (qui est efficace mais inélégant). Le choix t'appartient.
Notez que certains navigateurs modernes prennent en charge une méthode bind
sur chaque fonction, ce qui est plus efficace que =>
De CoffeeScript. Il y a un ticket ouvert pour que =>
Utilise le bind
natif lorsqu'il est disponible: https://github.com/jashkenas/coffee-script/pull/1408
Addendum: Bien sûr, une alternative plus efficace que tout ce qui précède serait d'écrire
for element, index in $('#my-table>tr')
...
ce qui résoudrait également votre problème this
.
Votre code...
class foo
@bar = 'bob loblaw'
processRows: ->
$("#my-table>tr").each ->
id = $(this).attr("id")
@processRow id
processRow: (id) ->
console.log @bar + id
Est transposé en ...
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;
})();
Ce qui a beaucoup supposé le contexte actuel dans lequel il se traduit. Malheureusement, puisque jQuery gère le contexte, vous devrez être explicite ou déclarer une référence au this
de votre classe.
Par ailleurs, il y a d'autres problèmes avec ce code généré, jetez un œil à ce cas réduit:
class foo
@bar = 'bob loblaw'
getBar: () ->
@bar
Transpile vers:
var foo;
foo = (function() {
function foo() {}
foo.bar = 'bob loblaw';
foo.prototype.getBar = function() {
return this.bar;
};
return foo;
})();
Les résultats de la tentative d'utilisation de ce morceau de code:
> foo.bar;
"bob loblaw"
> var f = new foo();
undefined
> f.getBar();
undefined
Votre code semble s'attendre à ce que @bar
est une propriété propre, mais elle est créée en tant que propriété statique de la fonction foo