2010-04-30 20 views
6

à jQuery fonction d'utilité jQuery.data() la documentation en ligne dit: méthodePourquoi la fonction .data() de jQuery est-elle préférable pour éviter les fuites de mémoire? En ce qui concerne

« Le jQuery.data() permet de attach données de tout type d'éléments DOM d'une manière qui est sûr . de références circulaires et donc de fuites de mémoire "

Pourquoi utiliser:

document.body.foo = 52; 

peut entraîner une fuite de mémoire -ou dans ce conditions- pour que je devrais utiliser

jQuery.data(document.body, 'foo', 52); 

Si je préfère toujours .data() au lieu d'utiliser expandos dans tous les cas?

(Je vous serais reconnaissant si vous pouvez fournir un exemple pour comparer les différences)

Merci,

Burak Ozdogan

+1

pourrait http://stackoverflow.com/questions/1056098/what-sort-of-memory-leaks-should-i-watch-for- avec-jquerys-data réponds à ta question? – Konerak

+0

Puis-je deviner? L'IE souffre de ce mal pendant une décennie. Mais AFAIK cela n'arrive que lorsque vous supprimez/détacher un élément DOM alors qu'il a encore des gestionnaires d'événements. – jweyrich

+0

@jweyrich: alors que IE a une notoriété célèbre pour les fuites de mémoire, les autres navigateurs ne sont pas à l'abri. –

Répondre

6

C'est mieux à cause de quelque chose que l'on peut lire dans la citation que vous avez donnée: "à l'abri des références circulaires".

Supposons que vous ayez les variables nodeOne et nodeTwo, qui référencent les nœuds.

Dites que vous mettez alors ce dans une fonction (dont la référence vous ne stockez pas):

jQuery.data(nodeOne, 'item', nodeTwo); 
jQuery.data(nodetwo, 'item', nodeOne); 

Après exécution de la fonction, il y a une référence circulaire: nodeOne a un arbitre à nodeTwo, et vice versa. En utilisant jQuery.data, cette référence circulaire n'empêchera pas que ces deux variables soient collectées.

Cependant, si vous deviez faire la même chose, mais sans utilisant jQuery.data, les variables nodeOne et nodeTwo ne seraient pas collectées ordures, même si les variables ne sont plus nécessaires.

-

Si je préfère toujours .data() au lieu d'utiliser expandos dans tous les cas?

À moins que vous faites de grandes quantités de réglage de données et ont besoin des gouttes supplémentaires de performance (et vous pourriez dire en utilisant le profilage) et sommes sûrs que vous ne serez pas créer des références circulaires (ou au moins un numéro cela aurait de l'importance), alors oui, vous pouvez tout aussi bien utiliser jQuery.data.

+0

Drôle, c'était un drive-by downvoted. – fig

+0

Attendez, votre exemple de code indique-t-il que '.data()' de jQuery fait ou ne laisse pas 'nodeOne' et' nodeTwo' récupérer le garbage? –

+0

@Crescent Frais, bon point, je vais le rendre plus clair. – fig

4

Je suis sûr que vous ne pouvez pas introduire une fuite de mémoire avec un valeur primitive comme 52. Les fuites de mémoire avec expandos se produisent généralement lorsqu'une valeur qui contient un objet avec une référence à l'élément est appliquée.

Je suggère de lire le contenu de la rubrique Référence circulaire au http://msdn.microsoft.com/en-us/library/Bb250448. Encore mieux, lisez tout :-)

Cela étant dit, je pense que la plupart des gens déconseillent d'utiliser expandos si possible (et c'est généralement possible). L'utilisation de data() de jQuery est une bonne alternative, dans tous les cas.


Je viens de réaliser que je n'ai pas répondu à votre question lol. data() de jQuery fournit une méthode qui va quelque chose comme ce qui suit:

  1. jQuery calcule un identifiant unique pour les données
  2. Les données sont stockées dans un objet disponible à la méthode data(), en utilisant l'ID unique
  3. Une propriété expando est appliquée à l'élément avec l'ID unique en tant que valeur primitive

Chaque fois que vous appelez data() pour récupérer les données, jQuery accède à la propriété expando pour l'ID unique et utilise cet ID pour récupérer les données de l'objet de mise en cache. Parce que expando contient une valeur primitive et n'a pas de pièce jointe à l'objet de mise en cache, aucune référence circulaire ne se produit.

+0

Merci Andy E's Head (Cela ressemble à quelque chose de Futurama! :)) Informations très utiles que vous avez fournies. – pencilCake

+0

@burak: Je suis un grand fan de Futurama :-) –