JQuery为什么不公开其UUID功能? [英] Why Doesn't JQuery Expose its UUID Functionality?

查看:118
本文介绍了JQuery为什么不公开其UUID功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在引擎盖下,JQuery使用"UUID"映射(只是它维护为jQuery.uuid的计数器)来解决当您将属性附加到Javascript中的DOM中的标记时浏览器遇到的众所周知的内存泄漏问题.取而代之的是,JQuery使用$.data(tag, name, value)将数据存储在uuid键(可以通过选中tag[jQuery.expando]确定的键)之外的映射中.

虽然$.data()非常有用,但有时您希望将数据映射到标签而不将数据转储到一个全局存储区中-您希望自己的较小数据存储区可以例如检查或的长度.遍历.

作为一个人为的示例,假设您具有单击时可在4种状态之一中旋转的图标.当一个处于状态2时,您想将其添加到状态2的图标数组中.但是这样做会导致内存泄漏.您可以在复选框上调用$.data(),但这并不能完全完成您要尝试执行的操作-您必须遍历所有复选框,对$.data()进行检查,以找出哪些是和哪些不是在列表中.

您需要将标签的一些抽象存储在数组中,这就是jQuery的UUID.您可以编写自己的UUID功能,但理想情况下,出于代码大小和质量方面的考虑,您只需要利用JQuery中已内置的UUID功能.您可以要求JQuery通过调用$.data(tag, 'irrelevant', 1)隐式地将UUID附加到标签上,然后检查tag[jQuery.expando]以获得其UUID,最后在列表中使用它……但这有点hacker.真正理想的是在公共API中公开以下内容:

$.getUuid(tag):检查并创建一个不存在的UUID-理想情况下,该方法应从$.data()中分解出来,并为传入的标签创建或获取uuid.

那么,有没有理由不在jQuery中将其排除在它自己的方法之外?这在某种程度上有害吗?只是从来没有看起来有用的东西吗?

我应该注意,我实际上已经在我们使用的jQuery版本中将其排除在外,这非常有帮助.但是也许我没有遇到潜在的风险.我还知道可以通过某种方式完成此操作的插件,但是它有点破损-具有2个代码路径来执行相同的UUID功能既浪费又有点脆弱.

解决方案

我认为,最明显的答案是jQuery构建了自己的uuid供内部使用,并且还没有看到使它成为可公开使用的理由或强烈要求.这并不意味着不存在原因,只是因为它们似乎还不足够重要,以至于无法使其成为需要处理的事情之首.

作为唯一ID使用单数递增的计数器很难实现,我已经使用了很多次.我觉得我并不需要类库支持.

我认为您担心内存泄漏,因为您将对象引用保留在周围有点夸张.首先,如果您摆脱了该对象却忘记摆脱了对该对象的某些引用,那只会是内存泄漏.这只是垃圾收集语言中的一条一般规则,您必须知道"要保留要删除的对象的引用,并在打算释放该对象时清理这些引用.

第二,如果您每页执行多次相同的操作,或者对象非常大,那么这只会是一次有意义的内存泄漏.当您进入下一页时,它们都会被清除,因此除非您永远不会离开该浏览器页面并且一遍又一遍地执行相同的操作(涉及被删除的对象,但不会被删除的引用),否则这似乎不会永远累积. /p>

第三,当使用DOM对象时,jQuery的.data()机制尝试为您解决很多此类问题.

第四,在您想像的示例中,除非您不再清理状态2不再有效或不再使用的图标阵列,否则不会造成内存泄漏.如果将其清理干净,则在该数组中存储直接DOM引用就没有问题.如果不清理数组,那么即使数组本身包含抽象的uuid而不是DOM引用,它甚至也是内存泄漏.在大多数情况下,使用抽象引用只需要大量工作.

同样,即使您泄漏它,泄漏也仅在页面寿命长并且您反复创建和释放对象时才很重要,但并不会清除所有对它们的引用,以致于随着时间的推移这些引用会累积并且这样做足以使它们引起的内存泄漏是有意义的.我一直在JS变量中保留对DOM对象的引用.我只是小心确保在不再需要它们时将它们归零,以便我知道可以在将来的某个时间释放DOM对象.

Underneath the hood JQuery uses a map of "UUIDs" (just a counter it maintains as jQuery.uuid) to work around the well-known memory leak issues browsers have when you attach a property to a tag in the DOM from Javascript. In lieu of doing so, JQuery uses the $.data(tag, name, value) to store data in a map keyed off of the uuid (a key that can be determined by checking tag[jQuery.expando]).

While $.data() is very useful, there are times you want to map data to tags without dumping that data into one global bucket - you want your own smaller bucket of data that you can, for example, check the length of or loop through.

As a contrived example, suppose you have icons that rotate through one of 4 states when clicked. When one is in state 2, you want to add it to an array of icons in state 2. The most obvious way to do so is to add the tag to an array; however doing so would create a memory leak. You could call $.data() on the checkbox, but that doesn't quite accomplish what you're trying to do - you'd have to loop through all the checkboxes checking $.data() against them to figure out which are and aren't in the list.

You need to store some abstraction of the tags in an array, and that's jQuery's UUIDs. You could write your own UUID functionality, but ideally you just leverage the UUID functionality already built-in to JQuery for both code-size and quality reasons. You could ask JQuery to attach a UUID to the tag implicitly by calling $.data(tag, 'irrelevant', 1) and then check tag[jQuery.expando] to get its UUID, and finally use that in the list... but that's a bit of a hack. Really what would be ideal is to have the following exposed in the public API:

$.getUuid(tag): Checks for and creates a UUID if none exists - ideally the method is factored out of $.data() and creates or fetches the uuid for the tag passed in.

So, is there a reason this isn't factored out into its own method in jQuery? Is this harmful in some way? Was it just never something that seemed useful?

I should note that I've actually factored it out in the version of jQuery we're using, and it's very helpful. But perhaps there's an underlying risk I'm not hitting in my usage. I'm also aware of a plugin that sort-of accomplishes this, but it's a bit broken - and having 2 codepaths to perform the same UUID functionality is both a bit wasteful and a bit brittle.

解决方案

I think the obvious answer here is that jQuery built their uuid for internal use and hasn't seen a great reason or great demand to bother making it publicly consumable. That doesn't mean reasons don't exist, just that they haven't seemed important enough for it to make it to the top of the list of things to work on.

Monotomically increasing counters to be used as unique IDs are pretty trivial to implement and I've used one many times. I didn't feel like I needed class library support for it to do so.

I think your fear of memory leaks because you keep object references around is a bit overblown. First off, it's only a memory leak if you get rid of the object and forget to get rid of some reference to it. That's just a general rule in garbage collected languages that you have to "know" where you're keeping references to objects that you may get rid of and clean up those references when you intend for the object to be freed.

Second, it's only a meaningful memory leak if you do the same thing a lot of times per page or if the object is very, very large. They all get cleaned up when you go onto the next page so it's not like it's something that accumulates forever unless you never leave that browser page and do the same thing over and over which involves removed objects, but references that aren't removed.

Third, jQuery's .data() mechanism attempts to solve a lot of this for you when using DOM objects.

Fourth, in your contrived example, this does not create a memory leak unless you don't clean up your array of icons in state 2 when it's no longer valid or no longer being used. If you clean it up, then there's no problem with storing a direct DOM reference in that array. If you don't clean up the array, then even the array itself is a memory leak, even if it has abstract uuids in it instead of DOM references. Using abstract references is just a lot more work than needed most of the time.

Again, even if you get it to leak, the leaks are only important if the page has a long life and you are repeatedly creating and releasing objects, but not clearing all references to them in a way that the references accumulate over time and doing this enough that the memory leak they cause is meaningful. I keep references to DOM objects in JS variables all the time. I am just careful to make sure that I null them out when I no longer need them so I know that the DOM object can be freed sometime down the road.

这篇关于JQuery为什么不公开其UUID功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆