Dans un fichier JavaScript, j'ai vu :
function Somefunction(){
var that = this;
...
}
Quel est le but de déclarer that
et d'assigner this
à celui-ci ?
Dans un fichier JavaScript, j'ai vu :
function Somefunction(){
var that = this;
...
}
Quel est le but de déclarer that
et d'assigner this
à celui-ci ?
Je vais commencer cette réponse par une illustration :
var colours = ['red', 'green', 'blue'];
document.getElementById('element').addEventListener('click', function() {
// this is a reference to the element clicked on
var that = this;
colours.forEach(function() {
// this is undefined
// that is a reference to the element clicked on
});
});
Ma réponse initiale démontrait cela avec jQuery, qui est seulement très légèrement différent :
$('#element').click(function(){
// this is a reference to the element clicked on
var that = this;
$('.elements').each(function(){
// this is a reference to the current element in the loop
// that is still a reference to the element clicked on
});
});
Parce que this
change fréquemment lorsque vous changez la portée en appelant une nouvelle fonction, vous ne pouvez pas accéder à la valeur originale en l'utilisant. L'alias en that
vous permet toujours d'accéder à la valeur originale de this
.
Personnellement, je n'aime pas l'utilisation de that
comme alias. Il est rarement évident à quoi il se réfère, surtout si les fonctions sont plus longues que quelques lignes. J'utilise toujours un alias plus descriptif. Dans mes exemples ci-dessus, j'utiliserais probablement clickedEl
.
Je vais généralement avec var self = this;
. Le mot that
semble impliquer que la variable est tout SAUF this
.
@David Oui, j'ai pensé que c'est quelque peu trompeur. Mais si, comme le dit Crockford, c'est une convention, est-il judicieux d'emprunter cette voie. Je suis totalement d'accord avec toi cependant, cela a beaucoup plus de sens.
@David : Voici mes pensées, var that = this et je me demande ce que c'est? Si l'implémentation utilisait self, je n'aurais probablement même pas eu à me poser la question.
De Crockford
Par convention, nous créons une variable privée that. Ceci est utilisé pour rendre l'objet disponible pour les méthodes privées. C'est une solution de contournement pour une erreur dans la spécification du langage ECMAScript, qui provoque une mauvaise définition de this pour les fonctions internes.
function usesThis(name) {
this.myName = name;
function returnMe() {
return this; //la portée est perdue en raison de la fonction interne
}
return {
returnMe : returnMe
}
}
function usesThat(name) {
var that = this;
this.myName = name;
function returnMe() {
return that; //la portée est incluse avec 'that' dans la "classe"
}
return {
returnMe : returnMe
}
}
var usesthat = new usesThat('Dave');
var usesthis = new usesThis('John');
alert("UsesThat pense s'appeler " + usesthat.returnMe().myName + '\r\n' +
"UsesThis pense s'appeler " + usesthis.returnMe().myName);
Ceci affiche une alerte...
UsesThat pense s'appeler Dave
UsesThis pense s'appeler undefined
J'ai lu cela, je n'ai pas compris parce qu'il n'y avait pas de détails, j'ai cherché sur Google, j'ai trouvé cette page. Où je suis à nouveau dirigé vers la même phrase. D'où le vote négatif.
C'est un point juste, je dirais que quelqu'un qui n'est pas familier avec JavaScript aurait du mal à saisir le concept juste avec ma réponse. J'ai répondu très brièvement (et j'ai mis un lien vers la page sur laquelle vous avez fait une recherche..) Je dirais que la réponse de lonesomeday est la plus claire, bien que j'aurais quand même préféré qu'elle soit en JS pur plutôt qu'en exemple jQuery.
Ceci est une astuce pour rendre les fonctions internes (fonctions définies à l'intérieur d'autres fonctions) plus efficaces. En javascript, lorsque vous définissez une fonction à l'intérieur d'une autre, this
est automatiquement défini sur la portée globale. Cela peut être déroutant car vous vous attendez à ce que this
ait la même valeur que dans la fonction externe.
var car = {};
car.starter = {};
car.start = function(){
var that = this;
// vous pouvez accéder à car.starter à l'intérieur de cette méthode avec 'this'
this.starter.active = false;
var activateStarter = function(){
// 'this' pointe maintenant vers la portée globale
// 'this.starter' est indéfini, donc nous utilisons 'that' à la place.
that.starter.active = true;
// vous pourriez aussi utiliser car.starter, mais utiliser 'that' donne
// plus de consistance et de flexibilité
};
activateStarter();
};
C'est spécifiquement un problème lorsque vous créez une fonction en tant que méthode d'un objet (comme car.start
dans l'exemple), puis créez une fonction à l'intérieur de cette méthode (comme activateStarter
). Dans la méthode de niveau supérieur this
pointe vers l'objet dont il s'agit d'une méthode (dans ce cas, car
) mais dans la fonction interne this
pointe maintenant vers la portée globale. C'est embêtant.
Créer une variable à utiliser par convention dans les deux portées est une solution à ce problème très général avec javascript (bien qu'elle soit également utile dans les fonctions jquery). C'est pourquoi le nom très général that
est utilisé. C'est une convention facilement reconnaissable pour surmonter une lacune dans le langage.
Comme El Ronnoco le suggère, Douglas Crockford pense que c'est une bonne idée.
Je suppose que cette réponse est plus utile que celle acceptée. Car elle clarifie la raison pour laquelle Crockford a inventé "that" tandis que la réponse sur jQuery ne le fait pas.
Il s'agit en fait d'un meilleur exemple que la réponse acceptée. Il explique ce que c'est comme "une erreur dans la spécification du langage ECMAScript qui entraîne que cela est incorrectement défini pour les fonctions internes", comme l'a dit Douglas.
Vous voudrez peut-être le rendre grammaticalement correct cependant. Je sais que c'est plus comme une faute de frappe, mais cela pourrait confondre les débutants en JavaScript car cette question est plutôt destinée aux débutants. Je veux dire que cela devrait être : var voiture = {}; voiture.démarrer = {}; voiture.démarrer = function() {...}
L'utilisation de that
n'est pas vraiment nécessaire si vous contournez en utilisant call()
ou apply()
:
var car = {};
car.starter = {};
car.start = function(){
this.starter.active = false;
var activateStarter = function(){
// 'this' points maintenant vers notre objet principal
this.starter.active = true;
};
activateStarter.apply(this);
};
Parfois this
peut faire référence à une autre portée et référencer autre chose, par exemple supposez que vous voulez appeler une méthode constructeur à l'intérieur d'un événement DOM, dans ce cas this
fera référence à l'élément DOM et non à l'objet créé.
HTML
Alert Name
JS
var Person = function(name) {
this.name = name;
var that = this;
this.sayHi = function() {
alert(that.name);
};
};
var ahmad = new Person('Ahmad');
var element = document.getElementById('button');
element.addEventListener('click', ahmad.sayHi); // => Ahmad
La solution ci-dessus assignera this
à that
, puis nous pouvons accéder à la propriété name à l'intérieur de la méthode sayHi
à partir de that
, donc cela peut être appelé sans problèmes à l'intérieur de l'appel DOM.
Une autre solution est d'assigner un objet vide that
et d'y ajouter des propriétés et des méthodes, puis de le renvoyer. Mais avec cette solution, vous perdez le prototype
du constructeur.
var Person = function(name) {
var that = {};
that.name = name;
that.sayHi = function() {
alert(that.name);
};
return that;
};
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
3 votes
Possible duplicate de var self = this?
9 votes
Le hack "this" et "that" n'est pas nécessaire pour les fonctions fléchées. Avec les fonctions fléchées, "this" fonctionne comme prévu. Voir ici pour plus de détails ES6 En Profondeur: Fonctions fléchées
1 votes
Ici le concept de ceci est expliqué scotch.io/@alZami/understanding-this-in-javascript
0 votes
Une excellente explication sur ce comportement mystérieux basée sur le contexte ici
1 votes
La dernière explication mise à jour peut être trouvée ici
0 votes
@Bergi Je ne pense pas que vous ayez réalisé qu'il demandait à propos de "ça" et non de "soi".
0 votes
@TrevorBlythe J'ai bien compris, et je faisais le lien avec l'autre question car c'est exactement le même sujet. S'il y avait des questions sur
var _this = this;
ouvar $this = this;
, nous les fermerions toujours en tant que doublons ; le nom de la variable n'a pas d'importance.0 votes
@TrevorBlythe Avouons-le, Qu'est-ce qui sous-tend cet idiome JavaScript :
var self = this
? serait une cible de duplication encore meilleure (si l'on en juge par l'ancienneté).