10

Вопрос по jquery, javascript, circular-reference – Как jQuery data () нарушает циклическую ссылку

Я прочиталwhy it's better а такжеhow it's implemented, Но что я действительно не понимаю, так этоhow does it break the circular reference?.

как это разрывает контрольный круг?

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

Например, приведенные выше элементы указывают друг на друга, как это предотвратить? У меня есть предчувствие, но я просто хочу убедиться, что мой догадка верна.

1 ответ
13

Проблема циклической ссылки возникает в некоторых браузерах

когда вы помещаете ссылку на объект DOM на объект DOM как свойство этого объекта DOM. Затем у вас есть два объекта DOM, указывающих друг на друга. Удаление объекта DOM с пользовательским свойством на нем не очищает это пользовательское свойство. Сборщик мусора, который не является таким интеллектуальным, не осознает, что эта ссылка на DOM не учитывается, поэтому он застревает, и существует несколько способов, которые могут привести к утечкам.

.data() решает эту проблему, потому что.data() данные НЕ находятся на объекте DOM. Это просто структура данных javascript, которая может быть связана с объектом 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(), то вы всегда должны удалять элементы из DOM, используя функции jQuery, так.data() очищен соответствующим образом. В противном случае вы можете получить утечки памяти таким образом (оба.data() данные могут утечь, и любые удаленные объекты DOM, на которые есть ссылки в.data() может протечь. Но, если вы используете только методы 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);

Поскольку вы удалили элемент DOM с простым Javascript, у jQuery не было возможности очистить ранее сохраненные данные. Сам элемент DOM будет собирать мусор, но.data() сохраненное ранее значение теперь потеряно в хранилище jQuery и, по сути, является «утечкой»; поскольку это, вероятно, никогда не будет очищено. С другой стороны, если вы сделаете это:

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

Затем jQuery увидит, что вы удаляете элемент DOM, а также очистит данные, которые вы сохранили с.data().

Довольно простой способ увидеть, как это работает, - создать сценарий из двух строк с не минимизированной версией jQuery, а затем просто выполнить вызов$(elem).data("key", "whatever") в отладчике и смотри как он работает.

Error: User Rate Limit Exceeded

от 

Error: User Rate Limit Exceeded

от 

Похожие вопросы