Je me demande actuellement s'il y a une meilleure solution que de passer (question mineure de côté: je lisais quelque chose à propos de la mémoire-fuites à JavaScript. Comment la fonction Lambda affecte-t-elle ma mémoire? Est-il préférable de Définissez-le d'abord comme var i = fonction (e) ... code> puis le transmettant comme un paramètre à seinterval?) p> p>
6 Réponses :
Qu'est-ce qui ne va pas avec simplement en s'appuyant sur la variable définie par la portée extérieure?
(function() { var x = {}; setInterval(function() { funkyFunction.call(x) }, speed); })();
Mon problème est que se trouve que seinterval est appelé une autre méthode de (dans votre exemple) 'x'. Donc, j'appelle essentiellement une méthode de l'autre et j'ai essayé de trouver une solution délicate autour de la fermeture, de la conservation d'un objet Hugh. Pensées tordues?
@Penthousepauper: Avoir une référence à l'objet dans une fermeture ne provoquera aucun problème de mémoire. Passer Ceci code> à
seinterval code> garderait l'objet en vie quand même. C'est également Firefox spécifique, de sorte que cela ne fonctionnera pas partout.
@Matthewcrumley Comment est-ce FF spécifique?
@Geronimo Cette réponse est bien; La partie spécifique FF transmet un paramètre à la fonction de rappel, comme dans la question.
Ma situation peut avoir été un peu différente, mais voici ce que j'ai fait:
var self = this; setInterval(function() { self.func() }, 50);
J'ai eu la même question, mais il semble y avoir une solution intégrée, voici une solution de contournement rapide que j'ai frappée ensemble: Utilisation: strong> < / p> couvre uniquement le cas d'utilisation dans lequel vous transmettez une fonction réelle, pas une chaîne de code à exécuter. p> comme pour votre question sur la mémoire Fuites Lors de l'utilisation de cette fonctionnalité: il n'est pas tant le problème avec l'utilisation de Je ne pense pas qu'il n'y ait aucun avantage d'attribuer la fonction à une variable d'abord, au contraire, ce sera Créez une autre variable contenant une référence qui ne sera pas déposée perçue tant que l'anon Func existe ... p> p> setInterval code> telle qu'elle est avec des fonctions anonymes en soi.
Si vous utilisez une référence à un objet à l'intérieur d'une Lambda, cette référence conservera l'objet référencé en mémoire aussi longtemps que la fonction anonyme existe. Je pense que la fonction est détruite avec un appel à
ClearInterval code>. P>
Désolé pour un commentaire tardif, mais je ne vois pas l'avantage d'utiliser setScopedInterval (fonction () {this.myfunc ();}, 1000, this) code> sur
setInval (fonction (x) {x .Myfunc ();}, 1000, this) code>. Que diriez-vous de
Var SetScopedInterval = (f, heure, étendue, ... p) => seinterval (x, p) => xf (... p), heure, périmètre, p); code> plutôt? Exemple Utilisation:
SetScopedInterval (this.myfunc, 1000, Ceci, P1, P2, P3) Code>.
En 2013, lorsque cette réponse a été postée, la fonction arrow n'était pas encore mise en œuvre dans JavaScript, c'est l'ensemble de la question de la question initiale. La différence entre les fonctions anonymes et les fonctions des arrows est l'héritage de la portée.
J'avais peur que ma notation moderne vous distrait du problème approprié ... et cela a fait. Mais oubliez cela, il y a des erreurs de niveau novice dans mon code: xf (... p) code> au lieu de
x [f] (... p) code> au lieu de < code> f.apply (x, p) code>. De même:
x.myfunc () code> au lieu de
x [myfunc] () code> au lieu de
myfunc.apply (x) code>. Les résoudre transforme mes solutions dans vos solutions et essentiellement répond à ma propre question. B>
Il y a encore d'autres questions: 1. B> Pourquoi setScopedInterval (fonction () {this.myfunc ();}, 1000, this); code> plutôt que
setScopedInval (ce .Myfunc, 1000, this); code>? 2. b> Pourquoi pas natif
seinterval (this.myfunc.bind (this), 1000); code> à la place? Y avait-il non
Bind code> méthode en 2013? 3. B> Pourquoi ne pas saisir cette opportunité et permettre
setScopedInterval code> également passer des arguments? Retour En 2013, Native
Seinterval Code> n'a pas permis de passer des arguments de passage à la fonction d'intervalle et de votre fonction pourrait la mettre en œuvre avec un code minimal. Comme ceci:
func.apply (portée, arguments) code>.
Vous pouvez également consulter le Utiliser YUI et JQUERY (n'oubliez pas Activer $ .noconflic ()) p> bref p> voir http://yuilibrary.com/yui /docs/aplass/classes/yui.html#method_later p> Mise à jour forte>
Pas besoin de $ .NOCONFLICT () parce que YUI n'utilise pas $ de quelque manière que ce soit. P> p> YUI code>
framework code>. C'est bien pour la construction d'applications et facile à apprendre.
Vous pouvez utiliser une fonction de liaison native. coller cet exemple dans la console pour voir le résultat P> P>
Il y a deux distinctions importantes à faire.
1) Voulez-vous une référence au paramètre transduit de sorte que la fonction Timeout puisse suivre les modifications apportées à elle, ou souhaitez-vous un clone du paramètre transumé? P>
2) Voulez-vous pouvoir capturer une référence au délai d'attente au cas où vous voulez l'annuler? (Oui!) P>
// Normal setTimeout: retains a reference to `test` and returns the bad value var test = 'test: good'; var timer = setTimeout(function() { console.log(test); }, 1000); test = 'test: bad'; // Test2 receives a clone of `test2` and returns the good value, but does so right away, not on a timeout var test2 = 'test2: good'; var timer2 = setTimeout((function() { console.log(test2); })(test2), 1000); test2 = 'test2: bad'; // Test3 receives a clone of `test3` and returns the good value, but doesn't return a reference to the timeout, and can't be canceled var test3 = 'test3: good'; var timer3 = function(test3) { setTimeout(function() { console.log(test3); }, 1000); }(test3); test3 = 'test3: bad'; // Test4 receives a clone of `test4` and returns the good value, and correctly returns timeout reference var test4 = 'test4: good'; var timer4 = function(test4) { return setTimeout(function() { console.log(test4); }, 1000); }(test4); test4 = 'test4: bad'; // Test5 retains a reference to `test5` and returns the bad value var test5 = 'test5: good'; var timer5 = setTimeout((function() { console.log(test5); }).bind(test5), 1000); test5 = 'test5: bad'; // Did we capture references to the timeouts? console.log(typeof timer); console.log(typeof timer2); console.log(typeof timer3); console.log(typeof timer4); console.log(typeof timer5);