6
votes

Stocker référence à la fonction dans Objet / Variable

J'ai cherché autour de là, mais jusqu'à présent n'a pas été en mesure de trouver un duplicata, je peux utiliser les mauvais mots-clés ...

J'essaie de changer temporairement une fonction stockée dans un objet, mais j'ai trouble le réglage de ce qu'il était auparavant.

Considérez ceci: xxx

puis dans une autre fonction: xxx < / Pre>

J'aurais attendu que l'affichage uniquement Fonction temporaire appelée une fois, il semble remplacer complètement l'ancien Succès Callback avec le rappel temporaire. < / p>

Quelqu'un peut-il me dire pourquoi et comment je peux me contenter de cela?

Je pensais que étendez corrigerait cela, mais il semble que le problème soit un peu plus profond. J'ai décidé de poster un extrait de mon code actuel cette fois-ci. Veuillez être conscient des points suivants avant de lire:

  1. sm est à peu près un alias de jQuery , veuillez l'ignorer.
  2. succès et erreur sont des paramètres fournis à la fonction

    Voici mon code: xxx


5 commentaires

Vous dites qu'après $ ('# foo'). Données ("bar", ancien_option); Vous voyez toujours fonction temporaire appelée ?


Quelques bonnes réponses là-bas.


Je suis un peu confus - cette nouvelle mise à jour, était-ce qu'après notre discussion de la copie peu profonde contre une copie profonde? Je vois que votre méthode succès est en fait une méthode options.success () (et similaire pour erreur ). C'est exactement la situation où une copie profonde serait nécessaire. Alors, les choses sont-elles toujours cassées ou la copie profonde fait-elle l'affaire?


@MichaelGeary non ceci est venu avant :-) le profond corrigé


Ouf! Tu m'as inquiet. Cela a du sens maintenant, en consultant votre code dans la mise à jour: la copie peu profonde aurait fonctionné avec votre code dans la question initiale, où le rappel Callback était une propriété de premier niveau de l'objet d'options principales. Mais le code réel de votre mise à jour est un peu différent: il dispose d'une fonction .OPTIONS.OPTIONS.PTIONS.SUCCESSE Fonction d'enfant directe mais deux niveaux. C'est exactement la situation où une copie profonde est nécessaire (ou au moins une copie plus spécialisée qui gérerait cet objet imbriqué).


4 Réponses :


10
votes

Lorsque vous exécutez ce code:

options.events.success = function(...) {...};


15 commentaires

C'est ce que je pensais faire. Devrais-je simplement utiliser la méthode JQuery EXTENDER ?


Parfait, merci!! N'était pas trop sûr de savoir comment verser la question mais je pensais que cela pourrait être la raison. Merci pour votre temps


C'est un peu plus compliqué que cela, c'est pourquoi je n'ai pas posté mon code. Pensez-y comme une extension de jQuery (c'est plus que cela mais pas vraiment pertinent). Si vous appelez $ ('# foo'). Barre (Options) Cela crée et instance de la barre. Et puis vous pouvez appeler $ ('# foo'). Barre ("Enregistrer", fonction () {}) qui exécute la méthode de sauvegarde et appelez le rappel fourni une seule fois, puis revenez à la Callback spécifié dans l'instance d'origine Options


C'est drôle, mais j'ajoutais cette ligne de code avec $. EXTENDRE () au moment même où vous écrivez ce commentaire en question! En plus, bien sûr toutes les autres réponses disant la même chose. Je suppose que le vieil adage est au moins parfois vrai: des grands esprits se ressemblent. :-)


Hahaha. Chose irritante est que j'allais essayer étendre () mais je ne pensais pas que cela aurait fait une différence ... aurait supprimé ce poste dès que j'ai vu votre réponse, mais comme vous l'avez eu Une telle bonne charge de représentant ne pensait pas que je le quitterais :-)


Okeydoke, bien la vraie question est de savoir ce que ces choses se passent de ces choses: qui prend une référence à ce succès et lorsqu'ils enregistrent-ils cette référence pour leur propre utilisation (ultérieure). Peut-être que vous allez bien, mais comme vous pouvez l'imaginer lorsque j'entends "enregistrer et restaurer des références d'objet / fonction" et "succès rappel" (qui semble asynchrone) dans le même souffle que je commence à m'inquiéter. :-)


"Comme tu as eu une telle grande charge de reps, je pensais que je le laisserais" - ah, c'est drôle et très gentil de ta part! Peut-être plus important est de savoir s'il sera utile aux futurs visiteurs - et j'espère que cela sera utile à quelqu'un.


Cela ne serait-il pas préférable d'ajouter automatiquement un rappel à la fonction exécutera et restaurer des paramètres anciens? L'exemple semble que vous voulez que cela se produise, peu importe.


@Justin peut-être, je peux le faire si je le vois si nécessaire.


@MichaelGeary Il est assez difficile d'expliquer l'ensemble du processus ici car il s'agit d'un script assez grand, et il est utilisé de différentes manières ... je pense que c'est trié cependant. Si j'avais des problèmes, je reviendrai. Merci beaucoup pour votre aide :-)


@Michaelgeary j'ai parlé trop tôt, se révèle étendre ne le réparait pas ... Jetez un coup d'œil à ma mise à jour pour voir ce que je fais réellement. C'est peut-être que je manque quelque chose d'évident ...


@MichaelGeary Je pense que votre dernière mise à jour a frappé le clou sur la tête. J'ai besoin d'une copie profonde car les options sont en fait un objet dans les propriétés. Cependant, JQuery offre le paramètre profond pour cela, ce serait sûrement certainement le trier? Ça n'a pas quand j'ai essayé ...


@MichaelGeary trié !!! J'appelle


Ah oui, j'ai oublié l'option profond à $. EXTENDIE () , merci pour le rappel. Je suis surpris que cela soit nécessaire, cependant, à moins d'autres objets imbriqués? Mais dans tous les cas si vous l'avez travaillé maintenant, c'est cool! Il n'y a pas d'inconvénient réel à l'utilisation de la copie profonde ici même si elle n'était pas nécessaire.


Et merci de faire rapport sur vos progrès et vos solutions. Dans l'esprit de faire cela utile pour les futurs visiteurs, j'ai mis à jour la réponse à inclure vos conclusions.



2
votes

Votre problème est que vous travaillez avec des objets. Vous passez des références à l'objet. L'objet sous-jacent est le même, tout ce que vous avez fait est d'ajouter une variable qui pointe à la même adresse.

Vous devrez cloner l'objet. Par exemple, créez un nouvel objet avec les mêmes propriétés et copiez-les.

Ce Post peut vous être utile. < / p>


0 commentaires

3
votes

Le problème est que options code> a une sémantique de référence: xxx pré>

Ce commentaire réside. Vous n'avez pas de copie des anciennes options; Plutôt, vous avez un autre référence em> sur le même objet d'options (un autre nom avec lequel vous pouvez vous y référer). p>

donc lorsque vous écrasez options.Success code >, ce changement est également visible sur old_options code>. Le code qui utilise .Data ​​code> pour stocker et revenir la valeur des options est redondant. P>

La seule chose que vous devez faire est la suivante: P>

var old_success = options.success;
options.success = function() { /* whatever */ };

// code that uses the new success callback

options.success = old_success; // restore original value


2 commentaires

@MichaelGeary l'a compris, mais un commentaire sur votre réponse. J'ai essayé à l'origine cette méthode mais cela a fini par exécuter options.Success ...


Même si la solution s'est révélée différente, vous obtenez un copieux +1 pour cette note: "Ce commentaire réside." C'est un point si important: souvent un bug est causé parce que nous pensons que le code Fait faire ce que dit un commentaire - que ce soit un commentaire explicite ou un "commentaire mental" - c'est-à-dire notre compréhension [MIS] du code. Il est trop facile de négliger un cas où nous pense le code fait une chose, mais cela en fait vraiment un autre. J'ai fait cela plusieurs fois, c'est comme ça que je sais :-)



2
votes

Lorsque vous faites ce var old_options = options Vous ne copiez pas les options les valeurs une référence . À partir de maintenant, Old_Options et Options Pointez sur le même point de mémoire et les modifications de l'un d'eux affectent les deux.


0 commentaires