En utilisant des méthodes d'instance comme pour les callbacks gestionnaires d'événements change la portée de this
de « Mon exemple » à « Tout ce que vient d' appeler la fonction de rappel » . Donc mon code ressemble à ceci
function MyObject() {
this.doSomething = function() {
...
}
var self = this
$('#foobar').bind('click', function(){
self.doSomethng()
// this.doSomething() would not work here
})
}
Cela fonctionne, mais est-ce la meilleure façon de procéder? Cela me semble étrange.
javascript
jquery
scope
closures
defnull
la source
la source
self
car il y a unwindow.self
objet et vous pourriez finir par l'utiliser accidentellement si vous oubliez de déclarer votre propreself
var (par exemple lorsque vous déplacez du code). Cela peut être ennuyeux à repérer / déboguer. Mieux vaut utiliser quelque chose comme_this
.this
est dynamique en JavaScript. Elle est déterminée lorsque la fonction est appelée , pas lorsqu'elle est déclarée."self === this
. Par conséquent,self
dans des contextes locaux, cela a du sens et suit le modèle.Réponses:
Cette question n'est pas spécifique à jQuery, mais spécifique à JavaScript en général. Le problème central est de savoir comment «canaliser» une variable dans les fonctions intégrées. Voici l'exemple:
Cette technique repose sur l'utilisation d'une fermeture. Mais cela ne fonctionne pas
this
car ilthis
s'agit d'une pseudo variable qui peut changer dynamiquement d'une portée à l'autre:Que pouvons-nous faire? Assignez-le à une variable et utilisez-le via l'alias:
this
n'est pas unique à cet égard:arguments
est l'autre pseudo variable qui devrait être traitée de la même manière - par aliasing.la source
Ouais, cela semble être une norme courante. Certains codeurs utilisent eux-mêmes, d'autres m'utilisent. Il est utilisé comme référence à l'objet «réel» par opposition à l'événement.
C'est quelque chose qui m'a pris un peu de temps pour vraiment comprendre, cela semble étrange au début.
Je fais généralement cela juste en haut de mon objet (excusez mon code de démonstration - c'est plus conceptuel qu'autre chose et n'est pas une leçon sur une excellente technique de codage):
la source
edit: malgré, les fonctions imbriquées dans un objet prennent l'objet de fenêtre globale plutôt que l'objet environnant.
la source
var self = this
fait, mais ce n'est pas ce que la question pose (la question est de savoir si c'est la meilleure solution au problème).Si vous faites ES2015 ou tapez script et ES5, vous pouvez utiliser les fonctions fléchées dans votre code et vous ne faites pas face à cette erreur et cela fait référence à la portée souhaitée dans votre instance.
la source
this
partir de leur champ d'application. Les définitions de fonction normales ne font pas cela.Une solution à cela est de lier tous vos rappels à votre objet avec la
bind
méthode javascript .Vous pouvez le faire avec une méthode nommée,
Ou avec un rappel anonyme
Faire cela au lieu de recourir à
var self = this
montre que vous comprenez comment la liaison dethis
se comporte en javascript et ne repose pas sur une référence de fermeture.En outre, l'opérateur de grosse flèche dans ES6 est fondamentalement le même qu'un appel
.bind(this)
à une fonction anonyme:la source
Je n'ai pas utilisé jQuery, mais dans une bibliothèque comme Prototype, vous pouvez lier des fonctions à une portée spécifique. Donc, avec cela à l'esprit, votre code ressemblerait à ceci:
La méthode bind renvoie une nouvelle fonction qui appelle la méthode d'origine avec la portée que vous avez spécifiée.
la source
$('#foobar').ready('click', this.doSomething.call(this));
non?bind
méthode ne fonctionne pas dans les navigateurs plus anciens, utilisez donc$.proxy
plutôt la méthode.En ajoutant simplement à cela, dans ES6 en raison des fonctions de flèche, vous ne devriez pas avoir besoin de le faire car elles capturent la
this
valeur.la source
Je pense que cela dépend en fait de ce que vous allez faire dans votre
doSomething
fonction. Si vous allez accéder auxMyObject
propriétés à l'aide de ce mot-clé, vous devez l'utiliser. Mais je pense que le fragment de code suivant fonctionnera également si vous ne faites rien de spécial en utilisant lesobject(MyObject)
propriétés.la source