Относительно к служебной функции jQuery jQuery.data () говорится в онлайн-документации:
"jQuery.data () метод позволяет нам присоединять данные любого типа к элементам DOM способом, который безопасен от циклических ссылок и поэтому из памяти протекает".
Почему использовать:
document.body.foo = 52;
может закончиться утечка памяти - или в том, какие условия - так, чтобы я использовал
jQuery.data(document.body, 'foo', 52);
Я должен ВСЕГДА предпочитать .data () вместо того, чтобы использовать expandos в любом случае?
(Я ценил бы, если можно обеспечить пример для сравнения различий),
Спасибо,
burak ozdogan
Он лучше именно потому, что в приведенной вами цитате сказано следующее: "безопасность от круговых ссылок".
Допустим, у вас есть переменные nodeOne
и nodeTwo
, которые ссылаются на узлы.
Допустим, вы помещаете это в функцию (ссылку на которую вы не храните):
jQuery.data(nodeOne, 'item', nodeTwo);
jQuery.data(nodetwo, 'item', nodeOne);
После выполнения функции возникает круговая ссылка: у nodeOne есть ссылка на nodeTwo, и наоборот.
При использовании jQuery.data эта круговая ссылка не помешает сборке мусора для этих двух переменных.
Однако, если вы сделаете то же самое, но без использования jQuery.data, переменные nodeOne
и nodeTwo
не будут собраны в мусор, даже если они больше не нужны.
--
Должен ли я ВСЕГДА предпочитать .data() вместо вместо использования expandos в любом случае?
Если только вы не занимаетесь установкой большого количества данных и не нуждаетесь в дополнительном падении производительности (а это можно определить с помощью профилирования) и уверены, что не будете создавать круговые ссылки (или хотя бы количество, которое будет иметь значение), то да, вы можете с тем же успехом использовать только jQuery.data.
Я почти уверен, что вы не можете создать утечку памяти с примитивным значением типа 52
. Утечки памяти с экспандерами обычно происходят, когда применяется значение, содержащее объект с обратной ссылкой на элемент.
Советую прочитать содержание заголовка Circular Reference по адресу http://msdn.microsoft.com/en-us/library/Bb250448. А еще лучше - прочитать все :-)
Учитывая это, я думаю, что большинство людей рекомендуют не использовать expandos, если это возможно (а обычно это возможно). Использование jQuery's data()
- хорошая альтернатива, в любом случае.
data()
предоставляет метод, который работает примерно следующим образом:
data()
, используя уникальный IDВсякий раз, когда вы вызываете data()
для получения данных, jQuery обращается к свойству expando для уникального ID и использует этот ID для получения данных из объекта кэширования. Поскольку свойство expando содержит примитивное значение и не имеет привязки к объекту кэширования, никаких циклических ссылок не возникает.