2010-04-30 4 views
6

Riguardo a jQuery funzione di utilità jQuery.data() la documentazione in linea dice:Perché la funzione .data() di jQuery è migliore per prevenire perdite di memoria?

"Il metodo

jQuery.data() ci permette di allegare dati di qualsiasi tipo di DOM elementi in un modo che è sicuro . da riferimenti circolari e quindi da perdite di memoria "

Perché usare:

document.body.foo = 52; 

può comportare una perdita di memoria -o in quello che condizioni- modo che dovrei usare

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

Dovrei preferisco sempre .data() invece di usare expandos in ogni caso?

(Gradirei se è possibile fornire un esempio per confrontare le differenze)

Grazie,

Burak Ozdogan

+1

http://stackoverflow.com/questions/1056098/what-sort-of-memory-leaks-should-i-watch-for- with-jquerys-data risponde alla tua domanda? – Konerak

+0

Posso indovinare? IE soffre di questo male per un decennio. Ma AFAIK accade solo quando rimuovi/rimuovi un elemento DOM mentre è ancora impostato su gestori di eventi. – jweyrich

+0

@jweyrich: mentre IE ha notorietà famosa per la perdita di memoria, altri browser non ne sono immuni. –

risposta

6

È meglio proprio a causa di qualcosa che dice nella citazione che hai dato: "al sicuro da riferimenti circolari".

Supponiamo di avere variabili nodeOne e nodeTwo, quali nodi di riferimento.

che hai poi mettere questo in una funzione (il cui riferimento non archiviare):

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

Dopo la funzione viene eseguita, c'è un riferimento circolare: nodeOne ha un ref per nodeTwo, e viceversa.

Utilizzando jQuery.data, quel riferimento circolare non impedirà che queste due variabili vengano triturate.

Tuttavia, se si dovesse fare la stessa cosa, ma senza utilizzando jQuery.data, i nodeOne e nodeTwo variabili non sarebbero spazzatura raccolti, anche se le variabili non sono più necessari.

-

caso preferisco sempre .data() invece di utilizzare expandos in ogni caso?

A meno che non si sta facendo grandi quantità di dati di impostazione e hanno bisogno di eventuali gocce in più di prestazioni (e si potrebbe dire utilizzando profiling) e sono sicuro che non sarà creare riferimenti circolari (o almeno un numero che sarebbe importante), allora sì, si può anche usare solo jQuery.data.

+0

Divertente, questo è stato il down-off drive-by. – fig

+0

Attendi, il tuo esempio di codice dice che '.data()' di jQuery fa o non consente a 'nodeOne' e' nodeTwo' di raccogliere i dati inutili? –

+0

@Crescent Fresh, buon punto, lo renderò più chiaro. – fig

4

Sono abbastanza sicuro che non è possibile introdurre una perdita di memoria con un valore primitivo come 52. Perdite di memoria con espansioni di solito si verificano quando viene applicato un valore che contiene un oggetto con un riferimento all'elemento.

Suggerisco di leggere il contenuto della voce di riferimento circolare http://msdn.microsoft.com/en-us/library/Bb250448. Ancora meglio, leggi tutto :-)

Detto questo, penso che la maggior parte delle persone sconsiglia di usare gli espansioni se possibile (e di solito è possibile). L'uso di jQuery data() è una buona alternativa, in ogni caso.


Ho appena realizzato che non ho risposto alla tua domanda lol. jQuery di data() fornisce un metodo che va qualcosa come il seguente:

  1. jQuery calcola un ID univoco per i dati
  2. i dati sono memorizzati in un oggetto a disposizione il metodo data(), utilizzando l'ID univoco
  3. An proprietà expando è applicato all'elemento con l'ID univoco come un valore di base

Ogni volta che si chiama data() per recuperare i dati, jQuery accede alla proprietà expando per l'ID univoco e utilizza tale ID per andare a prendere i dati dall'oggetto di memorizzazione nella cache. Poiché expando contiene un valore primitivo e non ha alcun allegato all'oggetto caching, non si verificano riferimenti circolari.

+0

Grazie Andy E's Head (Questo sembra qualcosa da Futurama! :)) Informazioni molto utili che hai fornito. – pencilCake

+0

@burak: Sono un grande fan di Futurama :-) –