265 votes

Comment transmettre ce contexte à une fonction ?

Je pensais que ce serait quelque chose que je pourrais facilement trouver sur Google, mais peut-être que je ne pose pas la bonne question...

Comment définir ce à quoi "this" fait référence dans une fonction javascript donnée ?

par exemple, comme pour la plupart des fonctions de jQuery telles que :

$(selector).each(function() {
   //$(this) gives me access to whatever selector we're on
});

Comment puis-je écrire/appeler mes propres fonctions autonomes qui ont une référence "this" appropriée lorsqu'elles sont appelées ? J'utilise jQuery, donc s'il y a une façon de faire spécifique à jQuery, ce serait idéal.

0 votes

0 votes

Je sais qu'il s'agit d'une vieille question, mais pour les autres qui atterrissent ici, voir jQuery $.proxy

352voto

jAndy Points 93076

Javascripts .call() y .apply() vous permettent de définir le contexte pour une fonction.

var myfunc = function(){
    alert(this.name);
};

var obj_a = {
    name:  "FOO"
};

var obj_b = {
    name:  "BAR!!"
};

Vous pouvez maintenant appeler :

myfunc.call(obj_a);

Ce qui alerterait FOO . Dans l'autre sens, le passage obj_b alerterait BAR!! . La différence entre .call() y .apply() est que .call() prend une liste séparée par des virgules si vous passez des arguments à votre fonction et .apply() a besoin d'un tableau.

myfunc.call(obj_a, 1, 2, 3);
myfunc.apply(obj_a, [1, 2, 3]);

Vous pouvez donc facilement écrire une fonction hook en utilisant le apply() méthode. Par exemple, nous voulons ajouter une fonctionnalité à jQuerys .css() méthode. Nous pouvons stocker la référence de la fonction d'origine, remplacer la fonction par du code personnalisé et appeler la fonction stockée.

var _css = $.fn.css;
$.fn.css = function(){
   alert('hooked!');
   _css.apply(this, arguments);
};

Puisque la magie arguments est un objet de type tableau, nous pouvons simplement le passer à apply() . De cette manière, nous garantissons que tous les paramètres sont transmis à la fonction d'origine.

6 votes

Un petit détail amusant : si vous devez appeler la fonction plusieurs fois en référence à obj_a par exemple, vous pouvez en créer une copie à l'aide de la fonction var boud_myfunc = myfunc.bind(obj_a) et appeler simplement bound_myfunc() si nécessaire.

58voto

palswim Points 4353

Utilisation function.call :

var f = function () { console.log(this); }
f.call(that, arg1, arg2, etc);

that est l'objet que vous souhaitez this dans la fonction à être.

2 votes

function est un mot-clé réservé ; pensez à mettre à jour votre réponse pour inclure une fonction nommée puisque function.call(...) n'est pas un code JavaScript valide.

1 votes

@DanielAllen : Sans la définition de l'exemple de nom de fonction que je fournirais, le code lancera toujours une erreur JS. Mais j'ai mis à jour le nom de la fonction exemple.

38voto

Joery Points 351

Autre exemple élémentaire :

Ne fonctionne pas :

var img = new Image;
img.onload = function() {
   this.myGlobalFunction(img);
};
img.src = reader.result;

Travailler :

var img = new Image;
img.onload = function() {
   this.myGlobalFunction(img);
}.bind(this);
img.src = reader.result;

En résumé, il suffit d'ajouter .bind(this) à votre fonction

33voto

Scott Jungwirth Points 361

Vous pouvez utiliser le lier pour définir le contexte de la fonction this à l'intérieur d'une fonction.

function myFunc() {
  console.log(this.str)
}
const myContext = {str: "my context"}
const boundFunc = myFunc.bind(myContext);
boundFunc(); // "my context"

17voto

Mic Points 13418

JQuery utilise un .call(...) pour assigner le nœud actuel à la méthode this à l'intérieur de la fonction que vous passez en paramètre.

EDIT :

N'hésitez pas à regarder dans le code de jQuery si vous avez un doute, tout est clair et bien documenté en Javascript.

ie : la réponse à cette question se trouve à la ligne 574,
callback.call( object[ name ], name, object[ name ] ) === false

Prograide.com

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.

Powered by:

X