J'ai une question concernant la façon dont le pointeur "this" est traité dans un scénario de fonction imbriquée.
Disons que j'insère cet exemple de code suivant dans une page Web. J'obtiens une erreur lorsque j'appelle la fonction imbriquée "doSomeEffects ()". J'ai vérifié dans Firebug et cela indique que lorsque je suis dans cette fonction imbriquée, le pointeur "this" pointe en fait vers l'objet "window" global - ce à quoi je ne m'attendais pas. Je ne dois pas comprendre quelque chose correctement car je pensais que depuis que j'ai déclaré la fonction imbriquée dans une fonction de l'objet, elle devrait avoir une portée "locale" par rapport à la fonction (c'est-à-dire que le pointeur "this" ferait référence à l'objet lui-même comme comment c'est dans ma première déclaration "si").
Tous les pointeurs (sans jeu de mots) seraient appréciés.
var std_obj = {
options : { rows: 0, cols: 0 },
activeEffect : "none",
displayMe : function() {
// the 'this' pointer is referring to the std_obj
if (this.activeEffect=="fade") { }
var doSomeEffects = function() {
// the 'this' pointer is referring to the window obj, why?
if (this.activeEffect=="fade") { }
}
doSomeEffects();
}
};
std_obj.displayMe();
la source
this
fait référence à l'objet sur lequel la fonction est appelée.var self = this;
et ensuite faire référenceself
dans la fonction interne via la fermeture.doSomeEffects
n'est associé à aucun objet en particulier, onthis
suppose donc que c'est la fenêtre, la mère de tous les éléments.Réponses:
En JavaScript, l'
this
objet est vraiment basé sur la façon dont vous effectuez vos appels de fonction.En général, il existe trois façons de configurer l'
this
objet:someThing.someFunction(arg1, arg2, argN)
someFunction.call(someThing, arg1, arg2, argN)
someFunction.apply(someThing, [arg1, arg2, argN])
Dans tous les exemples ci-dessus, l'
this
objet serasomeThing
. L'appel d'une fonction sans objet parent principal vous donnera généralement l' objet global qui, dans la plupart des navigateurs, signifie l'window
objet.la source
this.doSomeEffects();
fonction de votre réponse, mais cela ne fonctionne toujours pas. Pourquoi?this
en desthis.doSomeEffects()
points àstd_obj
. Comme expliqué dans la réponse ci-dessus, si une fonction n'a pas de référence d'objet, ellethis
doit être un objet de fenêtre.Comme cela semble être l'une des questions les plus votées du genre, permettez-moi d'ajouter, après toutes ces années, la solution ES6 utilisant les fonctions fléchées:
la source
this
ne fait pas partie de la portée de fermeture, il peut être considéré comme un paramètre supplémentaire à la fonction qui est liée au site d'appel. Si la méthode n'est pas appelée en tant que méthode, l'objet global est passé en tant quethis
. Dans le navigateur, l'objet global est identique àwindow
. Par exemple, considérons la fonction suivante,et l'objet suivant,
Si vous appelez la fonction en utilisant une syntaxe de méthode telle que,
alors
this
est lié àobj
.Si vous appelez directement someFunction (), comme,
puis
this
est lié à l'objet global, c'est-à-direwindow
.Le travail le plus courant consiste à capturer cela dans la fermeture, par exemple,
la source
Il y a une différence entre les variables de clôture et «ceci». "this" est en fait défini par l'invocateur de la fonction, tandis que les variables explicites restent intactes à l'intérieur du bloc de déclaration de fonction connu sous le nom d'enceinte. Voir l'exemple ci-dessous:
vous pouvez l'essayer ici: http://jsfiddle.net/kSTBy/
Ce qui se passe dans votre fonction est "doSomeEffects ()", est appelé explicitement, cela signifie le contexte ou le "ceci" de la fonction est la fenêtre. si "doSomeEffects" était une méthode prototype, par exemple this.doSomeEffects sur disons "myObject", alors myObject.doSomeEffects () ferait en sorte que "this" soit "myObject".
la source
_this.name = myFirstObject this.name = mySecondObject
Pour comprendre cette question, essayez d'obtenir le résultat de l'extrait de code suivant
Le code ci-dessus affichera les éléments suivants sur la console:
Dans la fonction externe, this et self font référence à myObject et peuvent donc correctement référencer et accéder à foo.
Dans la fonction interne, cependant, cela ne fait plus référence à myObject. En conséquence, this.foo n'est pas défini dans la fonction interne, alors que la référence à la variable locale self reste dans la portée et y est accessible. (Avant ECMA 5, cela dans la fonction interne ferait référence à l'objet de fenêtre global; alors que, à partir de ECMA 5, cela dans la fonction interne serait indéfini.)
la source
this
fait référence à l'objet window (dans un environnement de navigateur) ou à l'objet GLOBAL (dans un environnement node.js)this
ne fait plus référence à la fenêtreComme expliqué par Kyle, vous pouvez utiliser
call
ouapply
pour spécifierthis
dans la fonction:Voici ce concept appliqué à votre code:
JsFiddle
la source
J'ai également reçu un avertissement " Accès de référence potentiellement invalide à un champ de classe via ce "
la source
Comme cela n'a pas été mentionné, je mentionnerai que l'utilisation
.bind()
est une solution -Voici un exemple plus simple -
Il est vrai que l'utilisation d'une fonction de flèche
=>
semble plus simple et facile pour le programmeur. Cependant, il faut garder à l'esprit qu'une portée lexicale est susceptible de nécessiter plus de travail en termes de traitement et de mémoire pour configurer et maintenir cette portée lexicale, par rapport à la simple association d'une fonctionthis
à un pointeur via.bind()
.Une partie de l'avantage de développer des classes dans JS était de fournir une méthode pour rendre la
this
présence et la disponibilité plus fiables, pour s'éloigner de la programmation fonctionnelle et des portées lexicales, et ainsi réduire les frais généraux.De MDN
la source