168 votes

Comprendre $ .proxy () dans jquery?

De docs Je comprends que .proxy() changerait la portée de la fonction passée en argument. Quelqu'un pourrait-il m'expliquer cela mieux, pourquoi devrions-nous faire cela?

385voto

user113716 Points 143363

Ce qu'elle n'est elle garantit que la valeur de this en fonction de la valeur que vous désirez.

Un exemple courant est en setTimeout qui prend place à l'intérieur d'un click gestionnaire.

Prenez ceci:

$('#myElement').click(function() {
        // In this function, "this" is our DOM element.
    $(this).addClass('aNewClass');
});

Le but est assez simple. Lors de l' myElement est cliqué, il doit obtenir la classe aNewClass. À l'intérieur du gestionnaire d' this représente l'élément qui a été cliqué.

Mais que faire si nous voulions un court délai avant l'ajout de la classe? Nous pourrions utiliser un setTimeout pour l'accomplir, mais le problème, c'est que, quelle que soit la fonction que nous donnons à l' setTimeout, la valeur de this à l'intérieur de cette fonction sera window au lieu de notre élément.

$('#myElement').click(function() {
    setTimeout(function() {
          // Problem! In this function "this" is not our element!
        $(this).addClass('aNewClass');
    }, 1000);
});

Donc ce que nous pouvons faire à la place, c'est d'appeler $.proxy(), de l'envoyer à la fonction et à la valeur que nous voulons assigner à l' this, et il sera de retour d'une fonction qui permettra de conserver cette valeur.

$('#myElement').click(function() {
   // ------------------v--------give $.proxy our function,
    setTimeout($.proxy(function() {
        $(this).addClass('aNewClass');  // Now "this" is again our element
    }, this), 1000);
   // ---^--------------and tell it that we want our DOM element to be the
   //                      value of "this" in the function
});

Ainsi, après nous avons donné $.proxy() la fonction, et la valeur que nous voulons pour l' this, il est retourné une fonction qui permettra de s'assurer que this est correctement défini.

Comment fait-il? Elle retourne une fonction anonyme qui appelle notre fonction à l'aide de l' .apply() méthode, qui permet de définir explicitement la valeur de this.

Un look simplifié la fonction qui est retournée peut ressembler à:

function() {
    // v--------func is the function we gave to $.proxy
    func.apply( ctx );
    // ----------^------ ctx is the value we wanted for "this" (our DOM element)
}

Donc, cette fonction anonyme est donnée à l' setTimeout, et il ne fait qu'exécuter notre fonction d'origine avec le bon this contexte.

51voto

jAndy Points 93076

Sans entrer dans les créateur de détails (ce qui serait nécessaire, parce que ce est sur le Contexte dans ECMAscript, cette variable de contexte etc.)

Il existe trois types différents de "Contextes" dans ECMA-/Javascript:

  • Le contexte mondial
  • Fonction du contexte
  • eval contexte

Chaque code est exécuté dans son contexte d'exécution. Il y a un contexte mondial et il peut y avoir plusieurs instances de la fonction (et eval) contextes. Maintenant la partie intéressante:

Chaque appel d'une fonction entre dans la fonction excution contexte. Un contexte d'exécution d'une fonction ressemble à:

L'Activation De L'Objet
La Portée De La Chaîne D'
cette valeur

Ainsi le cette valeur est un objet spécial qui est en rapport avec le contexte d'exécution. Il y a deux fonctions dans ECMA-/Javascript qui peut changer la cette valeur en fonction du contexte d'exécution:

.call()
.apply()

Si nous avons une fonction foobar() on peut changer le présent en appelant:

foobar.call({test: 5});

Maintenant, nous pourrions accéder en foobar l'objet, nous avons passé en:

function foobar() { 
    this.test // === 5
}

C'est exactement ce qu' jQuery.proxy() . Il prend un function et context (qui n'est rien d'autre qu'un objet) et les liens de la fonction en invoquant .call() ou .apply() et retourne cette nouvelle fonction.

4voto

sgv_test Points 269
I had written this function

 function my_proxy (func,obj)
  {
      if (typeof(func)!="function") return;

// If obj is empty or another set another object 
       if (!obj) obj=this;

   return function () { return func.apply(obj,arguments); }
  }

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