2012-04-04 11 views

risposta

12

Il problema di riferimento circolare si verifica in alcuni browser quando si mette un riferimento a un oggetto DOM su un oggetto DOM come una proprietà su tale oggetto DOM. Quindi, hai due oggetti DOM puntati l'uno verso l'altro. La rimozione di un oggetto DOM con una proprietà personalizzata non cancella quella proprietà personalizzata. Un garbage collector che non è così intelligente non si rende conto che questo riferimento DOM non conta, quindi rimane bloccato e ci sono diversi modi in cui questo può portare a perdite.

.data() risolve questo problema perché i dati .data() NON si trovano nell'oggetto DOM. È solo una struttura dati javascript che può essere associata all'oggetto DOM tramite un ID stringa univoco.

Quello confondendo parte di questo è che quando si legge con .data("key") e la key non si trova nella struttura di dati .data() javascript, allora e solo allora, jQuery cercherà un attributo sull'oggetto DOM chiamato "data-key". Ma ogni volta che scrivi con .data("key", "myData"), non scrive mai sull'oggetto DOM, ma solo sulla struttura dei dati javascript.

Pertanto, dal momento che .data() non scrive mai i dati sull'oggetto DOM, non ci può essere nessuno di questi tipi di riferimenti circolari con cui alcuni browser hanno problemi.

Ci sono altre cose utili da sapere sulla struttura dati .data(). Quando si utilizza jQuery .remove() per rimuovere elementi dal DOM o quando si chiama $(elem).html("new html"), jQuery cancella i dati .data() su tutti gli elementi rimossi. Questo è un caso in cui è bene non mischiare jQuery con un semplice javascript. Se si utilizza .data(), è necessario rimuovere sempre gli elementi dal DOM utilizzando le funzioni jQuery in modo che .data() vengano eliminati in modo appropriato. In caso contrario, è possibile ottenere perdite di memoria in questo modo (entrambi i dati .data() possono perdere e gli eventuali oggetti DOM rimossi con riferimento nello .data() possono perdere. Tuttavia, se si utilizzano solo metodi jQuery per rimuovere elementi dal DOM (inclusa la sostituzione di innerHTML), poi jQuery pulire le cose in modo appropriato e non ci saranno perdite

Così, per esempio, questo creerà una perdita di memoria:.

// suppose elem is a DOM element reference 

// store some data in jQuery's data storage on behalf of a DOM element 
$(elem).data("someKey", "someValue"); 

// remove DOM element with plain Javascript 
elem.parentNode.removeChild(elem); 

Perché è stato rimosso l'elemento DOM con piano JavaScript, jQuery non ha avuto la possibilità di ripulire i dati precedentemente memorizzati. L'elemento DOM stesso sarà spazzato via, ma il valore .data() è stato precedentemente memorizzato il rosso è orfano nella memoria di jQuery ed è essenzialmente una "perdita" in quanto probabilmente non verrà mai cancellato. D'altra parte, se si esegue questa operazione:

$(elem).data("someKey", "someValue"); 
$(elem).remove(); 

Poi, jQuery vedrà che si sta rimuovendo l'elemento DOM e sarà anche cancellare i dati è stato memorizzato con .data().

Un modo abbastanza semplice per vedere come funziona è creare uno script di linea di coppia con una versione non ridotta di jQuery e quindi semplicemente passare una chiamata a $(elem).data("key", "whatever") nel debugger e osservare come funziona.

+0

Potresti per favore illustrare la tua spiegazione sul paragrafo 5 con un esempio? –

+0

@ techloris_109 - Esempio aggiunto. – jfriend00

Problemi correlati