Почему JQuery не раскрывает свою функциональность UUID? - PullRequest
6 голосов
/ 12 августа 2011

Под капотом JQuery использует карту «UUID» (просто счетчик, который он поддерживает как jQuery.uuid), чтобы обойти известные браузеры проблемы утечки памяти, когда вы присоединяете свойство к тегу в DOM из Javascript , Вместо этого JQuery использует $.data(tag, name, value) для хранения данных на карте, отключенной от uuid (ключ, который можно определить, установив tag[jQuery.expando]).

Хотя $.data() очень полезно, бывают случаи, когда вы хотите отобразить данные в теги без сброса этих данных в один глобальный блок - вам нужен собственный меньший пакет данных, с которым вы можете, например, проверить длину или цикл через.

В качестве надуманного примера, предположим, что у вас есть значки, которые при нажатии поворачиваются через одно из 4 состояний. Когда кто-то находится в состоянии 2, вы хотите добавить его в массив значков в состоянии 2. Наиболее очевидный способ сделать это - добавить тег в массив; однако это может привести к утечке памяти. Вы можете позвонить $.data() на флажок, но это не совсем то, что вы пытаетесь сделать - вам придется пройтись по всем флажкам, проверяя $.data() против них, чтобы выяснить, какие есть, а какие нет в списке.

Вам нужно хранить некоторую абстракцию тегов в массиве, и это UUIDs в jQuery. Вы можете написать свою собственную функциональность UUID, но в идеале вы просто используете функциональность UUID, уже встроенную в JQuery, как по размеру кода, так и по качеству. Вы могли бы попросить JQuery неявно присоединить UUID к тегу, вызвав $.data(tag, 'irrelevant', 1), а затем проверив tag[jQuery.expando], чтобы получить его UUID, и, наконец, использовать его в списке ... но это немного хак. Действительно, было бы идеально, если бы в публичном API было открыто следующее:

$.getUuid(tag): проверяет и создает UUID, если его не существует - в идеале метод извлекается из $.data() и создает или выбирает UUID для переданного тега.

Итак, есть ли причина, по которой это не учитывается в его собственном методе в jQuery? Это как-то вредно? Разве это никогда не казалось полезным?

Я должен отметить, что я фактически учел это в используемой нами версии jQuery, и это очень полезно. Но, возможно, есть основополагающий риск, который я не использую. Я также знаю о плагине, который вроде бы выполняет это, но он немного сломан - и наличие 2-х путей кода для выполнения той же функциональности UUID является и немного расточительным и немного ломким.

Ответы [ 2 ]

4 голосов
/ 12 августа 2011

Я думаю, что очевидный ответ здесь заключается в том, что jQuery создал свой uuid для внутреннего использования и не видел веских причин или большого требования, чтобы сделать его общедоступным. Это не означает, что причин не существует, просто они не казались достаточно важными для того, чтобы он оказался на вершине списка вещей, над которыми нужно работать.

Монотомически увеличивающиеся счетчики для использования в качестве уникальных идентификаторов довольно тривиальны для реализации, и я использовал один много раз. Я не чувствовал, что мне нужна поддержка библиотеки классов для этого.

Я думаю, что ваш страх утечки памяти, потому что вы храните ссылки на объекты, немного преувеличен. Во-первых, это только утечка памяти, если вы избавляетесь от объекта и забываете избавиться от какой-либо ссылки на него. Это просто общее правило в языках сборки мусора, которые вы должны «знать», где вы храните ссылки на объекты, от которых вы можете избавиться, и очищать эти ссылки, когда вы собираетесь освободить объект.

Во-вторых, это значительная утечка памяти, если вы делаете одно и то же много раз на странице или если объект очень, очень большой. Все они очищаются, когда вы переходите на следующую страницу, поэтому не похоже, что это что-то накапливается вечно, если вы никогда не покинете эту страницу браузера и не делаете одно и то же снова и снова, что включает в себя удаленные объекты, но ссылки, которые не удалены.

В-третьих, механизм jQuery .data () пытается решить эту проблему за вас при использовании объектов DOM.

В-четвертых, в вашем надуманном примере это не приведет к утечке памяти, если вы не очистите массив значков в состоянии 2, когда он больше не действует или больше не используется. Если вы очистите его, то нет проблем с сохранением прямой ссылки DOM в этом массиве. Если вы не очистите массив, то даже сам массив является утечкой памяти, даже если он содержит абстрактные uuids вместо ссылок DOM. Использование абстрактных ссылок - это гораздо больше работы, чем нужно в большинстве случаев.

Опять же, даже если у вас есть утечка, утечки важны только в том случае, если страница имеет длительный срок службы, и вы неоднократно создаете и выпускаете объекты, но не очищаете все ссылки на них таким образом, чтобы ссылки накапливались с течением времени. и делать это достаточно, чтобы утечка памяти, которую они вызывают, имела смысл. Я постоянно храню ссылки на объекты DOM в переменных JS. Я просто стараюсь сделать так, чтобы я обнулял их, когда они мне больше не нужны, поэтому я знаю, что объект DOM может быть освобожден в будущем.

0 голосов
/ 14 июня 2013

Это было отправлено команде jQuery и отклонено.

Однако вы можете поддерживать список тегов, которые делегируют сборку мусора в jQuery, например:

http://jsfiddle.net/b9chris/Un2mH/

Необходимый код:

sets[oldIndex] = sets[oldIndex].not(this);
sets[index] = sets[index].add(this);

Хотя это создает отдельную нагрузку на память - эти методы не только добавляют тег в массив, но и поддерживают стек предыдущих состояний этой коллекции (.pushStack () вызывается внутри). Если страница является долгоживущей с большим количеством действий пользователя, коллекции будут расти без ограничений. Чтобы предотвратить это, вы можете взломать объекты для удаления стека:

sets[oldIndex] = sets[oldIndex].not(this);
sets[oldIndex].prevObject = null;
sets[index] = sets[index].add(this);
sets[index].prevObject = null;

Трата некоторых циклов процессора, но достаточно чистая.

...