Que signifie "var that = this;" En JavaScript?
dans un fichier JavaScript j'ai vu:
function Somefunction(){
var that = this;
...
}
Quel est le but de déclarer that
et de l'affecter à this
?
6 réponses
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 l'a d'abord démontré avec jQuery, ce qui n'est que 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 souvent quand vous changez la portée en appelant une nouvelle fonction, vous ne pouvez pas accéder à la valeur originale en l'utilisant. L'alias 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 fait référence, surtout si les fonctions sont plus longues que quelques lignes. J' toujours utiliser un plus descriptif alias. Dans les exemples ci-dessus, j'utiliserais probablement clickedEl
.
À Partir De Crockford
par convention, nous faisons un privé que variable. Ceci est utilisé pour faire de l' objet disponible pour le privé méthode. C'est une solution de contournement pour un erreur dans le langage ECMAScript Spécification qui fait que ce est incorrectement définies pour les fonctions internes.
function usesThis(name) {
this.myName = name;
function returnMe() {
return this; //scope is lost because of the inner function
}
return {
returnMe : returnMe
}
}
function usesThat(name) {
var that = this;
this.myName = name;
function returnMe() {
return that; //scope is baked in with 'that' to the "class"
}
return {
returnMe : returnMe
}
}
var usesthat = new usesThat('Dave');
var usesthis = new usesThis('John');
alert("UsesThat thinks it's called " + usesthat.returnMe().myName + '\r\n' +
"UsesThis thinks it's called " + usesthis.returnMe().myName);
cette Alerte...
Usthat thinks it's called Dave
UsesThis pense qu'il est appelé indéfini
il s'agit d'un hack pour faire fonctionner les fonctions internes (définies dans d'autres fonctions) comme elles devraient le faire. En javascript, lorsque vous définissez une fonction à l'intérieur d'une autre this
est automatiquement défini à la portée globale. Cela peut prêter à confusion 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;
// you can access car.starter inside this method with 'this'
this.starter.active = false;
var activateStarter = function(){
// 'this' now points to the global scope
// 'this.starter' is undefined, so we use 'that' instead.
that.starter.active = true;
// you could also use car.starter, but using 'that' gives
// us more consistency and flexibility
};
activateStarter();
};
C'est spécifiquement un problème lorsque vous créez une fonction comme une méthode d'un objet (comme car.start
dans le exemple) puis créer une fonction à l'intérieur de cette méthode (comme activateStarter
). Dans la méthode du niveau supérieur this
pointe vers l'objet c'est une méthode de (dans ce cas, car
) mais dans la fonction interne this
pointe maintenant vers la portée globale. C'est une douleur.
créer une variable à utiliser par convention dans les deux sens est une solution pour ce problème très général avec javascript (bien qu'il soit utile dans les fonctions jquery, aussi). C'est pourquoi le son très général le nom that
est utilisé. Il est facilement reconnaissable convention pour surmonter une lacune dans la langue.
Comme El Ronnoco allusion à de Douglas Crockford pense que c'est une bonne idée.
L'utilisation de that
n'est pas vraiment nécessaire si vous apporter une solution avec l'utilisation de call()
ou apply()
:
var car = {};
car.starter = {};
car.start = function(){
this.starter.active = false;
var activateStarter = function(){
// 'this' now points to our main object
this.starter.active = true;
};
activateStarter.apply(this);
};
parfois this
peut se référer à une autre portée et se référer à autre chose, par exemple supposons que vous voulez appeler une méthode de constructeur à l'intérieur d'un événement DOM, dans ce cas this
se référera à l'élément DOM et non à l'objet créé.
HTML
<button id="button">Alert Name</button>
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 vise this
à that
puis nous pouvons accéder à la propriété nom à l'intérieur de la méthode sayHi
à partir de that
, de sorte que cela peut être appelé sans problèmes à l'intérieur de L'appel DOM.
une autre solution consiste à attribuer un objet vide that
et à y ajouter des propriétés et des méthodes, puis à le retourner. Mais avec cette solution, vous avez perdu le prototype
du constructeur.
var Person = function(name) {
var that = {};
that.name = name;
that.sayHi = function() {
alert(that.name);
};
return that;
};
Voici un exemple
$(document).ready(function() {
var lastItem = null;
$(".our-work-group > p > a").click(function(e) {
e.preventDefault();
var item = $(this).html(); //Here value of "this" is ".our-work-group > p > a"
if (item == lastItem) {
lastItem = null;
$('.our-work-single-page').show();
} else {
lastItem = item;
$('.our-work-single-page').each(function() {
var imgAlt = $(this).find('img').attr('alt'); //Here value of "this" is '.our-work-single-page'.
if (imgAlt != item) {
$(this).hide();
} else {
$(this).show();
}
});
}
});
});`
donc vous pouvez voir que la valeur de ceci est deux valeurs différentes selon L'élément DOM que vous ciblez mais quand vous ajoutez" que "au code ci-dessus vous changez la valeur de" ceci " que vous ciblez.
`$(document).ready(function() {
var lastItem = null;
$(".our-work-group > p > a").click(function(e) {
e.preventDefault();
var item = $(this).html(); //Here value of "this" is ".our-work-group > p > a"
if (item == lastItem) {
lastItem = null;
var that = this;
$('.our-work-single-page').show();
} else {
lastItem = item;
$('.our-work-single-page').each(function() {
***$(that).css("background-color", "#ffe700");*** //Here value of "that" is ".our-work-group > p > a"....
var imgAlt = $(this).find('img').attr('alt');
if (imgAlt != item) {
$(this).hide();
} else {
$(this).show();
}
});
}
});
});`
..... $(qui).css ("background-color", "#ffe700"); //ici valeur de" cela "est".notre-groupe de travail > p> a " parce que la valeur de var qui = cela, alors même si nous sommes à "ce"= '.notre-work-single-page', nous pouvons toujours utiliser "that" pour manipuler L'élément DOM précédent.