Использование свойств хранилища данных jQuery vs. expando

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

Скажем, ради чрезвычайно упрощенного аргумента, что я хочу сохранить свойство "lineNumber" с каждой строкой в ​​ "интересной" таблице.

Вариант 1 должен был просто установить свойство expando для каждого элемента DOM (я надеюсь, что правильно использую термин "expando" ):

$('.interesting-line').each(function(i) { this.lineNumber = i; });

Вариант 2 будет использовать функцию jQuery data() для связывания свойства с элементом:

$('.interesting-line').each(function(i) { $(this).data('lineNumber', i); });

Игнорируя любые другие недостатки моего кода примера, есть ли веские причины, по которым вы выбрали бы одно средство хранения свойств над другим?

Ответ 1

Если вы создаете плагин, вы должны использовать $.data. Если вам нужно хранить атрибут часто и редко нужно запрашивать DOM для него, используйте $.data.

Сказав, что для всех моих клиентских приложений я склонен хранить пользовательские атрибуты DOM непосредственно в элементе DOM, чтобы потом я мог их запросить с помощью атрибута [] selector:

var domElement = $('.interesting-line[lineNumber=' + lineNumber + ']').get(0);

Это более читаемо, чем повторение завернутого набора, вызывающего .data() для каждого элемента. Часто я взаимодействую с другой сторонней библиотекой, которая работает с элементом DOM, поэтому быстрый и легкий доступ к элементу DOM с помощью этого механизма сохраняет читаемый код.

Это так же просто, как хранить сопоставление таблицы обращений lineNumbers к элементам, однако метод атрибута expando менее подвержен риску утечки памяти в сравнении, поскольку вы не храните ссылки на элементы DOM, которые вам нужно очистить позже. Забастовкa >

Обновление через 5 лет Просто прочитайте это после того, как он получил [заслуженный] downvote: пожалуйста, проигнорируйте приведенный выше текст. jQuery не запрашивает DOM на основе установленных свойств expando, и не сделал этого некоторое время. Поэтому используйте $.data. Нет причин для загрязнения DOM, когда для этого нет прагматичного использования.

Ответ 2

Использование $.data защитит вас от утечек памяти.

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

Хранилище данных jQuery настроено для предотвращения формирования этих циклов. Если вы его используете, вы не будете утечки памяти таким образом. Ваш пример не будет протекать, потому что вы помещаете примитивы (строки) в элемент DOM. Но если вы разместите там более сложный объект, вы рискуете протекать.

Используйте $.data, поэтому вам не придется беспокоиться.

Ответ 3

Использование $.data не изменяет DOM. Вы должны использовать $.data. Если вы создаете плагин, вы должны сохранить один объект в $.data со свойствами на этом объекте, а не хранить каждое из этих свойств как разные пары ключ/значение в структуре $.data.