2012-04-04 21 views

Respuesta

12

El problema de referencia circular ocurre en algunos navegadores cuando pone una referencia a un objeto DOM en un objeto DOM como una propiedad en ese objeto DOM. Entonces, tienes dos objetos DOM apuntando el uno al otro. La eliminación de un objeto DOM con una propiedad personalizada no borra esa propiedad personalizada. Un recolector de basura que no es tan inteligente no se da cuenta de que esta referencia DOM no cuenta, por lo que se atasca y hay varias formas en que esto puede provocar filtraciones.

.data() resuelve este problema porque los datos .data() NO están en el objeto DOM. Es solo una estructura de datos de JavaScript que se puede asociar con el objeto DOM a través de una ID de cadena única.

El confundiendo parte de esto es que cuando se lee con .data("key") y la key no se encuentra en la estructura de datos .data() Javascript, entonces y sólo entonces, jQuery buscará un atributo en el objeto DOM llamada "data-key". Pero cada vez que escribe con .data("key", "myData"), nunca escribe en el objeto DOM, solo en la estructura de datos de JavaScript.

Por lo tanto, dado que .data() nunca escribe los datos en el objeto DOM, no puede haber ninguno de estos tipos de referencias circulares que algunos navegadores tienen problemas.

Hay otros elementos útiles que debe saber sobre la estructura de datos .data(). Cuando utiliza jQuery's .remove() para eliminar elementos del DOM o cuando llama al $(elem).html("new html"), jQuery borra los datos .data() en cualquier elemento eliminado. Este es un caso en el que es bueno no mezclar jQuery con javascript simple. Si usa .data(), siempre debe eliminar los elementos del DOM utilizando las funciones de jQuery para que .data() se limpie adecuadamente. De lo contrario, puede obtener pérdidas de memoria de esta manera (los datos de .data() pueden filtrarse y cualquier objeto DOM eliminado al que se haga referencia en .data() puede tener fugas. Pero, si solo utiliza métodos jQuery para eliminar elementos del DOM (incluido el reemplazo de innerHTML), a continuación, jQuery limpiar las cosas de manera adecuada y no habrá fugas

Así, por ejemplo, esto creará una pérdida de 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); 

al haber retirado el elemento DOM con sencillo Javascript, jQuery no tuvo la oportunidad de limpiar los datos que almacenó previamente. El elemento DOM en sí será basura, pero el valor .data() que previamente el rojo ahora está huérfano en el almacenamiento de jQuery y es esencialmente una "fuga", ya que probablemente nunca se borre. Por otro lado, si usted hace esto:

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

Entonces, jQuery verá que usted está quitando el elemento DOM y también borrará los datos que se almacenan con .data().

Una forma bastante sencilla de ver cómo funciona es crear un script de dos líneas con una versión no minimizada de jQuery y luego simplemente hacer una llamada al $(elem).data("key", "whatever") en el depurador y ver cómo funciona.

+0

¿Podría por favor ilustrar su explicación sobre el párrafo 5 con un ejemplo? –

+0

@ techloris_109 - Ejemplo agregado. – jfriend00

Cuestiones relacionadas