jQuery / JavaScript "cette" confusion de pointeur
Le comportement de "this" lorsque la fonction bar
est appelée me déconcerte. Voir le code ci-dessous. Existe-t-il un moyen de faire en sorte que "this" soit une ancienne instance d'objet JS lorsque bar est appelée à partir d'un gestionnaire de clics, au lieu d'être l'élément html?
// a class with a method
function foo() {
this.bar(); // when called here, "this" is the foo instance
var barf = this.bar;
barf(); // when called here, "this" is the global object
// when called from a click, "this" is the html element
$("#thing").after($("<div>click me</div>").click(barf));
}
foo.prototype.bar = function() {
alert(this);
}
7 réponses
Bienvenue dans le monde de javascript! : D
Vous avez erré dans le domaine de la portée et de la fermeture javascript.
Pour la réponse courte:
this.bar()
Est exécuté dans le champ d'application de foo, comme ce désigne foo)
var barf = this.bar;
barf();
Est exécuté sous la portée globale.
Ceci.bar signifie essentiellement:
Exécute la fonction pointée par ceci.bar, sous la portée de Ce (foo). Quand tu as copié ça.bar à barf, et exécuter barf. Javascript compris comme, exécutez la fonction pointée par barf, et comme il n'y a pas Ce , Il fonctionne juste dans la portée globale.
Pour corriger cela, vous pouvez modifier
barf();
À quelque chose comme ceci:
barf.apply(this);
Cela indique à Javascript de lier la portée de this à barf avant de l'exécuter.
Pour les événements jquery, vous devrez utiliser une fonction anonyme ou étendre la fonction bind dans prototype pour prendre en charge la portée.
Pour plus info:
Il y a une bonne explication sur le mot clé this
en JavaScript disponible à QuirksMode .
Vous pourriez trouver ceci:
Le Contrôle de la valeur de 'cette' jQuery événement
Ou ceci:
Http://www.learningjquery.com/2007/08/what-is-this
Utile.
Obtenez le livre: JavaScript: les bonnes parties.
Aussi, lisez autant que vous le pouvez par Douglas Crockford http://www.crockford.com/javascript/
Vous pouvez utiliser Function.apply
sur la fonction pour définir ce à quoi this
devrait se référer:
$("#thing").after($("<div>click me</div>").click(function() {
barf.apply(document); // now this refers to the document
});
C'est parce que ce est toujours l'instance que la fonction est attaché. Dans le cas d'un Gestionnaire d'événements c'est la classe qui a déclenché l'événement.
Vous pouvez vous aider avec une fonction anonyme comme celle-ci:
function foo() {
var obj = this;
$("#thing").after($("<div>click me</div>").click(function(){obj.bar();}));
}
foo.prototype.bar = function() {
alert(this);
}
this.bar(); // when called here, "this" is the foo instance
Ce commentaire est faux lorsque foo est utilisé comme une fonction normale, pas comme un constructeur. ici:
foo();//this stands for window