[Перевод] jQuery считается вредным
Хех, мне всегда хотелось написать один из этих «Х считается вредным» постов :)Прежде чем я начну, позвольте сказать следующее: я считаю что jQuery оказал просто невероятное влияние на продвижение Web. Он дал возможность разработчикам делать такие вещи, которые ранее считались немыслимыми. Заставил производителей браузеров реализовать многие фичи нативно (без jQuery у нас наверное никогда бы не появился document.querySelectorAll). jQuery всё еще нужен тем кто не может положиться на современные плюшки и вынужден поддерживать реликты вроде IE8 или хуже.Тем не менее, как бы я не сочувствовала этим бедным ребятам, они в меньшинстве. Сегодня существуют уже тонны разработчиков, которым не нужно поддерживать старые браузеры с их мизерной долей на рынке. И давайте не будем забывать тех, кто не является профессиональными разработчиками: студенты и исследователи, им не только побоку вся эта кроссбраузерность, часто им вообще ничего не нужно кроме одного единственного браузера! Наверное вы ожидаете, что в академических кругах, все с удовольствием пользуются новомодными плюшками Открытой Веб Платформы? И близко нет, jQuery там просто везде. Почему? Потому что jQuery — это всё что они знают, у них просто нет ни сил, ни времени следить за новинками веба. Им не нужна причина, чтобы использовать jQuery, он просто должен быть использован. Несмотря на этот факт, и возможность уже делать все эти вещи нативно, я всё же считаю, что это не это основная причина избегать jQuery.Да, скорее всего, он вам не нужен…Определенно я далеко не первый, кто обращает внимание на то, что почти всё что умеет jQuery, сегодня умеет и нативный JavaScript. Так что я не буду повторятся и просто дам несколько ссылок: Так же я не буду тратить время, рассуждая о размере файла и о том, насколько быстрее работают нативные методы. Это все уже не раз разжевано. Сегодня я хочу обратить внимание на кое-что другое.…, но это всё же не та причина чтобы отказаться от его использования Чтобы избежать расширения прототипов нативных объектов, jQuery использует собственные обертки над этими объектами. В прошлом, расширять нативные объекты, считалось огромным минусом, и не столько из-за потенциальных коллизий с другими расширениями, сколько из-за постоянных утечек памяти в IE6. Так и пошло с тех пор, вызов $('div') вернет нам не ссылку на элемент или список нод, а некий jQuery-объект. Это означает, что jQuery-объект содержит совершенно другие методы, чем обычная ссылка на дом-элемент или список нод. Тем не менее, эти ссылки всё время вылазят наружу в реальных проектах. Как бы jQuery не старался абстрагироваться от них, вам все равно постоянно приходится оперировать ими, пусть даже просто оборачивая эти ссылки в $(). Например, контекст коллбэка в случае вызова метода jQuery .bind () будет ссылкой на дом элемент, а не на коллекцию jQuery. Так же стоит отметить, что вы часто используете библиотеки из разных источников, некоторые из них нуждаются в jQuery, а некоторые нет. Всё это приводит к тому, что на выходе нас ждет адская смесь из нативных дом элементов, списков нод и jQuery-объектов.Если разработчик придерживается соглашения об именовании jQuery-объектов (добавляя $ перед именем переменной) и обычных переменных содержащих ссылки на нативные элементы, то это безусловно сглаживает проблему (хотя люди имеют свойство забывать о любых конвенциях, но допустим что мы живем в идеальном мире). Как бы то ни было, в большинстве случаев, разработчики и слыхом не слыхивали о подобных конвенциях, и в результате в их коде чрезвычайно трудно разобраться незнакомым с ним людям. Каждая попытка отредактировать такой код, влечет множество ошибок в стиле «Ох, блин, это не jQuery-объект, забыл обернуть его в $()» или «Черт, тут же не дом-элемент забыл взять его через $(…)[0]». Чтобы избежать конфузов, разработчики часто заканчивают тем, что начинают вообще всё подряд оборачивать в $(), на всякий случай. Читая код после, можно увидеть, что одна и та же переменная оборачивается в $() множество раз. По той же причине, становится очень трудно, отрефакторить этот код так, чтобы он не использовал jQuery. Так что по сути получаем безвыходную ситуацию.
Даже если вы строго соблюдаете соглашение о наименовании переменных, все равно часто возникает ситуация, когда вам нужно вызвать нативный метод для дом-элемента или запустить функцию из кода, который не зависит от jQuery. И через какое-то время ваш код уже будет забит сверху донизу переводами объектов из jQuery в нативные и наоборот.
Допустим, через какое-то время, вы решите дописать еще пару фич для подобной программы и в большинстве случаев вы закончите тем, что опять обернете все новые ссылки на дом элементы и коллекции в $(). Ведь вы не всегда можете точно знать, в каком случае вам понадобиться та или иная ссылка. Так что опять она, безвыходная ситуация, которая еще и распространяется на весь будущий код!
Возьмите любой случайный скрипт с jQuery-зависимостью и попробуйте его от этой зависимости избавить. Разбежались. Вы увидите что основная ваша задача не конвертировать методы в нативные, а вообще понять что тут за ад происходит.
Прагматичный путь к чистому JS Разумеется, сегодня многие библиотеки требуют jQuery и как я недавно твитнула, попытки полностью от него избавиться будут похожи на некое цифровое веганство. И всё же это не значит, что вам нужно продолжать пользоваться им. Библиотеки всегда могут быть заменены в будущем, когда появятся их версии не использующие jQuery.Кроме того, многие библиотеки написаны так, что они не требуют наличия именно переменной $ как синонима jQuery. Просто вызовите jQuery.noConflict () чтобы забрать себе переменную $ и найти ей лучшее применение. Например я часто использую эти фукнции-помощники, вдохновившись Command Line API:
// Возвращаем первый элемент, который соответствует CSS селектору {expr}. // Запросы могут быть ограничены потомками {container}-а function $(expr, container) { return typeof expr === «string»? (container || document).querySelector (expr) : expr || null; }
// Возвращаем все элементы которые соответствуют CSS селектору {expr} в виде массива. // Запросы могут быть ограничены потомками {container}-а function $$(expr, container) { return [].slice.call ((container || document).querySelectorAll (expr)); } Кроме того, я думаю что если вам придется каждый раз вместо $ набирать jQuery, то вы дважды подумаете, а действительно ли оно мне надо? ИМХО конечно :)
Так же, если вам действительно очень нравится jQuery API, но вы хотите избежать раздувания кода, подумайте об использовании Zepto.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.