javascript - jQuery data() 如何打破循环引用

标签 javascript jquery circular-reference

我读过 why it's betterhow it's implemented .但我不太明白的是它如何打破循环引用?

它是如何打破引用圈的?

$(div1).data('item', div2);
$(div2).data('item', div1);

比如上面的div相互指向,如何防止?我有预感,但我只是想确定我的预感是否正确。

最佳答案

当您将对 DOM 对象的引用作为该 DOM 对象的属性放置在 DOM 对象上时,某些浏览器会发生循环引用问题。然后,您有两个相互指向的 DOM 对象。删除带有自定义属性的 DOM 对象并不会清除该自定义属性。一个不那么聪明的垃圾收集器没有意识到这个 DOM 引用没有计​​数,所以它被卡住了,并且有几种方法可以导致泄漏。

.data() 解决了这个问题,因为 .data() 数据不在 DOM 对象上。它只是一个 javascript 数据结构,可以通过唯一的字符串 ID 与 DOM 对象相关联。

其中一个令人困惑的部分是,当您使用 .data("key") 读取时,key 未在 javascript 中找到。 data() 数据结构,然后并且只有到那时,jQuery 才会在 DOM 对象上查找名为 "data-key" 的属性。但是每当你用 .data("key", "myData") 编写时,它永远不会写入 DOM 对象,只会写入 javascript 数据结构。

因此,由于 .data() 从不将数据写入 DOM 对象,因此不会存在某些浏览器无法处理的任何此类循环引用。

关于 .data() 数据结构,还有一些其他有用的知识需要了解。当您使用 jQuery 的 .remove() 从 DOM 中删除元素或当您调用 $(elem).html("new html") 时,jQuery 会清除 .data() 任何已删除项目的数据。在这种情况下,最好不要将 jQuery 与纯 javascript 混合使用。如果您正在使用 .data(),那么您应该始终使用 jQuery 函数从 DOM 中删除项目,以便适本地清理 .data()。否则,您可能会以这种方式发生内存泄漏(.data() 数据可能泄漏,并且 .data() 中引用的任何已删除 DOM 对象都可能泄漏。但是,如果您只使用 jQuery 方法从 DOM 中删除项目(包括替换 innerHTML),那么 jQuery 将适本地清理内容并且不会有泄漏。

因此,例如,这将造成内存泄漏:

// 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);

因为您使用纯 Javascript 删除了 DOM 元素,所以 jQuery 没有机会清理您之前存储的数据。 DOM 元素本身将被垃圾收集,但是您之前存储的 .data() 值现在在 jQuery 的存储中成为孤立的,并且本质上是一个“泄漏”,因为它可能永远不会被清除。另一方面,如果您这样做:

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

然后,jQuery 会看到您正在删除 DOM 元素,并且还会清除您使用 .data() 存储的数据。

查看其工作原理的一种相当简单的方法是使用非最小化版本的 jQuery 创建几行脚本,然后逐步调用 $(elem).data("key", "whatever") 在调试器中观察它是如何工作的。

关于javascript - jQuery data() 如何打破循环引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10004593/

相关文章:

javascript - 将分数转换为十六进制

javascript - Site_url 在导航栏 codeigniter 3 中不起作用

javascript - 将树 json 数据填充到下拉框

json - 将循环结构转换为 JSON——有什么方法可以找到它提示的字段?

jquery - 将传递对您正在使用 .bind 的对象的引用会导致循环引用

javascript - 在 Meteor.js 中将变量范围设置为模板

jquery - 如果一行中只有一个可见的表格单元格,如何动态添加 .attr ('colspan' , '100' )?

javascript - Firefox session 不会自动删除

javascript - CKEditor - 获取编辑器数据和自定义小部件

Excel:如果在某些空间布局中输入,循环计算将不会收敛