Страницы

Поиск по вопросам

суббота, 21 декабря 2019 г.

Обоснование необходимости повторного вызова функции jQuery, когда объект уже создан

#javascript #jquery


Допустим, мы хотим повесить обработчик события на кнопку

var messagesBtn = $("#menu_btn-messages");


В переменную messagesBtn у нас уже записан объект jQuery, и по идее теперь мы можем
вызывать методы этого обекта:

messagesBtn.on('click', function(){
      ...
    });


Тем не менее, насколько я видел в примерах, пишут:

$(messagesBtn).on('click', function(){
  ...
});


Получается, мы рекурсивно вызываем $($("#menu_btn-messages")). Прокомментируйте,
пожалуйста, это явление.
    


Ответы

Ответ 1



Когда вы пишете var messagesBtn = $("#menu_btn-messages"), вы записываете результат выполнения функции $() в переменную messagesBtn. В этой переменной хранится состояние элемента на момент присваивания переменной. Зачем так делают? Ну, на то есть как минимум 2 причины. Первая и главная причина - это оптимизация. Такой процесс, кажется, называется кэшированием селекторов, но я могу ошибаться. Короче говоря, при каждом вызове функции $() происходят какие-то вычисления, которые тратят ресурсы (поиск элемента, построение jQuery-объекта и т.п.). Чтобы эти ресурсы лишний раз не тратить, объекты jQuery (и не только их - с обычными элементами DOM на ванильном JavaScript делают то же самое) часто помещают в переменные. Вот два теста: Первый: var iterations = 1000000; console.time('Function #1'); for (var i = 0; i < iterations; i++) { $('body').attr('title', 'test'); $('body').attr('title', 'foo'); $('body').attr('title', 'baz'); } console.timeEnd('Function #1'); Второй: var iterations = 1000000; console.time('Function #1'); for (var i = 0; i < iterations; i++) { var $body = $('body'); $body.attr('title', 'test'); $body.attr('title', 'foo'); $body.attr('title', 'baz'); } console.timeEnd('Function #1'); Лично у меня первый тест выполнялся медленнее второго в 2 раза на Chrome 55.0.2883.87 m (64-bit) для Windows 10. На самом деле, подобное кэширование не очень-то и сильно влияет на производительность в реальных условиях. Разница в скорости, конечно, в 2 раза, но обычный вызов функции $() выполняется слишком быстро, и если во всем сценарии у вас парочка вызовов, то разницу вы не заметите. Но кэширование нужно использовать, если вы работаете с jQuery из событий, которые выполняются невероятно часто. Например, событие скролла или событие ресайза окна браузера. Было бы неплохо приучить себя постоянно писать с использованием переменных. Вторая причина, почему так делают - это читаемость кода и удобство его поддержки. Для лучшей читаемости рекомендуется переменные, содержащие jQuery-объект, именовать с символом доллара в начале (чтобы обозначить, что в переменной находится jQuery-объект), как во втором тесте, и давать имя, основанное не на имени класса или ID, а на значении (назначении) элемента. Таким образом, вы можете изменить имя селектора лишь в одном месте и не бояться, что вы где-то что-то забыли. Что происходит, когда вы передаете jQuery-объект в функцию $(), например $($("#menu_btn-messages"))? Да ничего интересного и необычного. Разработчики jQuery таким образом лишь предотвратили возможные путаницы в коде. Но так делать не рекомендуется - это лишняя трата ресурсов.

Комментариев нет:

Отправить комментарий