Прежде чем я начну, позвольте сказать следующее: я считаю что jQuery оказал просто невероятное влияние на продвижение Web. Он дал возможность разработчикам делать такие вещи, которые ранее считались немыслимыми. Заставил производителей браузеров реализовать многие фичи нативно (без jQuery у нас наверное никогда бы не появился document.querySelectorAll). jQuery всё еще нужен тем, кто не может положиться на современные плюшки и вынужден поддерживать реликты вроде IE8 или хуже.
Тем не менее, как бы я не сочувствовала этим бедным ребятам, они в меньшинстве. Сегодня существуют уже тонны разработчиков, которым не нужно поддерживать старые браузеры с их мизерной долей на рынке. И давайте не будем забывать тех, кто не является профессиональными разработчиками: студенты и исследователи, им не только побоку вся эта кроссбраузерность, часто им вообще ничего не нужно кроме одного единственного браузера! Наверное, вы ожидаете, что в академических кругах, все с удовольствием пользуются новомодными плюшками Открытой Веб Платформы? И близко нет, jQuery там просто везде. Почему? Потому что jQuery — это всё что они знают, у них просто нет ни сил, ни времени следить за новинками веба. Им не нужна причина, чтобы использовать jQuery, он просто должен быть использован. Несмотря на этот факт, и возможность уже делать все эти вещи нативно, я всё же считаю, что это не это основная причина избегать jQuery.
Да, скорее всего, он вам не нужен...
Определенно я далеко не первая, кто обращает внимание на то, что почти всё, что умеет jQuery, сегодня умеет и нативный JavaScript. Так что я не буду повторятся и просто дам несколько ссылок:
- А нужен ли вам jQuery?
- Наверное, вам не нужен jQuery
- Вам точно не нужен jQuery!
- 10 советов как писать на JavaScript без jQuery
- …и так далее. Просто загуглите “вам не нужен jQuery” и вас завалят советами.
Также я не буду тратить время, рассуждая о размере файла и о том, насколько быстрее работают нативные методы. Это все уже не раз разжевано. Сегодня я хочу обратить внимание на кое-что другое.
… но это всё же не та причина чтобы отказаться от его использования
Чтобы избежать расширения прототипов нативных объектов, 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.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Комментарии (147)
Methos
01.06.2015 12:47-8кто не может положиться
mlg
01.06.2015 15:20-2Пропустили:
в каком случае вам понадобиться та или иная ссылка
На всякий случайshoomyst
01.06.2015 13:14+2Тем не менее, как бы я не сочувствовал
и как я недавно твитнул
Автор заметки Lea Verou вроде пока еще девушка, нет? :)shoomyst
01.06.2015 13:25+1Ну а что касается jQuery: не у всех разработчиков есть время/желание разбираться в тонкостях JS, проще прочитать неплохой мануал jQ и заюзать пару методов
poxu
01.06.2015 14:16А я вот скажу, что не у всех разработчиков есть время/желание разбираться в JQuery. Такие дела :).
Acuna
01.06.2015 15:02+2А, то есть на лишнюю писанину у них время есть?
IonDen Автор
01.06.2015 15:06Просто далеко не всем нужно всё то что предлагает jQuery. Если на повестке дня только работа с дом и события, то можно вообще не вникать.
Acuna
01.06.2015 15:19+1Да, это так, просто лично у меня как-то так получается, что половина моего основного проекта можно сказать просто написана на jQuery!) Страшно представить, если бы это был бы нативный JS)
poxu
01.06.2015 15:17-1Нередко лишней писанины не надо.
Например если хочется найти элемент по css селектору или повесить event.
Но, когда ищешь элемент по селектору, jQuery вернёт тебе не ноду из DOM, а свою обертку и об этом надо помнить. Тут jQuery больше мешает, чем помогает.Acuna
01.06.2015 17:42А, тут да, соглашусь. Однако лично мне тот же AJAX, например, просто необходим, но писать его поддержку на нативном JS — как минимум бессмысленно. Поэтому и таскаю за собой везде и jQuery и jQuery UI по всем проектам. На скорость особо не влияет, однако более 60% функционала из них обоих мне всегда пригождалось. Всегда. Ибо все любят всякие ползунки, приятности, окошки и ajax'ы…
poxu
01.06.2015 18:25У меня похожая история. Но вроде есть полифилы для запросов и промисов. Думаю заюзать их.
VolCh
01.06.2015 17:58Именно. Если знаешь как решить задачу пятью строчками своего кода, то нет смысла изучать апи чужого, чтобы не писать свой. Тем более чужой читать всё равно придется, чтобы убедиться, что он содержит именно те 5 строк, которые ты собирался написать.
nomadmoon
02.06.2015 03:11+1lea.verou.me/wp-content/uploads/2011/05/smiling.jpg
По крайней мере выглядит как девушка :)
P.S. Картинкой или ссылкой почему то не вставляется :(
lavkasnov
01.06.2015 13:19+8Как обойтись без одного .on на родителе, чтобы не вешать сотню onclick на детях? Как быть без defered и callbacks? Как быть без namespace в событиях (хочу сменить порядок обработки событий)? Нормализация ajax запросов? Что искать по отдельности в каждом фремворке и ждать потом их багфиксов?
IonDen Автор
01.06.2015 13:30-2On: learn.javascript.ru/event-delegation все норм
Defered и promise: да, с нативной поддержкой пока туго в IE, но есть полифилы
Ajax: youmightnotneedjquery.com/#request, нормализация не нужна с IE10
Неймспейсы в событиях: ну чтож тут я пас, для них лучше jQuery я ничего не знаю, но не везде они нужны.GreatRash
01.06.2015 14:23+2В плане AJAX вы показали примитивнейшую реализацию. У jQuey всё намного сложнее — больше плюшек.
IonDen Автор
01.06.2015 14:53developer.mozilla.org/ru/docs/Web/API/XMLHttpRequest не вижу тут никакого примитива.
jgunchenko
01.06.2015 14:14+11Совсем от jQuery отказываться пока нет смысла. Да и тем более с учетом сколько jQuery кода на проде у большинства висит. Скорее нужно отказаться от подхода «пишем на jQuery везде, где можно и нельзя».
Acuna
01.06.2015 15:26-6«Автор заметки Lea Verou вроде пока еще девушка, нет?»
При всем моем уважении к слабому полу.SelenIT2
01.06.2015 16:05+4Ну, кроме этого она еще и автор dabblet.com и еще кучи проектов, а также крутой книги по CSS, и эксперт W3C по нему же впридачу… думаю, слабость пола здесь мало на что влияет:)
Acuna
03.06.2015 01:29Ооо, прямо таки осознал после этого неправомерность своего громкого заявления!)
zyaleniyeg
01.06.2015 14:14+7Обычное: «Я попробовал X и теперь буду всем рассказывать почему Y говно»
RubaXa
01.06.2015 14:15+2Приведенные в статье функции $/$$ вернут отличный результат от jQuery и многие об этом забывают, когда использую querySelector.
Это я не в сторону защиты использования jQuery, а ради справедливости.Acuna
01.06.2015 17:30Да можно и в сторону защиты вообще-то) Ибо отказ от него в любом случае очень сомнительная идея.
javist
01.06.2015 14:19+2Когда делаете embed javascript решения, типа виджетов (например Комментарии или Отзывы), jQuery, к сожалению, только портит (особенно на мобильных платформах), пришли к этому выводу на своем опыте, в итоге написали маленькую библиотеку для работы с DOM, которая по некоторым операциям, к примеру .parents(), работает в 1500 раз быстрее ))
Вообщем для каждой задачи свои решения.
Houston
01.06.2015 14:21+1Для Ajax, так как в браузерах появляется fetch-API, уже можно начинать использовать его через полифиллы github.com/github/fetch
k12th
01.06.2015 14:35Отхвачу, наверное, минусов, но все-таки:
Мне в jQuery больше всего не нравится, что опечатку в селекторе обнаружить невозможно — вернули тебе пустой массив, и ты, счастливый, вешаешь на него события, меняешь ему классы, а потом недоумеваешь — почему не работает-то. Early errors рулят.
Еще мне не нравится чейнинг — брейкпойнт в середину не поставишь. Особенное зло — вещи вида:
$elem.addClass('opened').find('button').click(function () { alert(123) })
Масса ненужных шорткатов типа #click, #focus, #change, которые все равно рано или поздно приходится переделывать на $elem.on('event', '.selector'), потому что они не умеют делегацию событий. Хотя вообще работа с событиями сделана неплохо (за исключением того, что обработчик выполняется в бесполезном, как правило, контексте DOM-элемента).
Еще куча ненужностей — всякие #wrap, #unwrap, #replaceWith и прочее манипулирование DOM-деревом, которое имело смысл только в эпоху отсутствия клиентских шаблонизаторов.
Поведение #each, которое передает в итератор не (elem, index, array), как это сделано везде, а (index, elem) — вообще полное WTF. Туда же jQuery.proxy.
Промизы не соответствуют стандарту и when ведет себя неконсистентно.
Я бы хотел иметь библиотеку для простой работы с DOM, только без лишнего барахла, без легаси, без неуклюжих костылей для того, что браузеры давно уже умеют нативно.
padre62
01.06.2015 14:39Все jquery да jquery, а кто что скажет по поводу zepto(кто юзал или перешел на него)? Какие плюсы/минусы?
enleur
01.06.2015 14:47с 2013 года он не обновлялся судя по ченжлогам
IonDen Автор
01.06.2015 15:08+1Судя по Гитхабу: github.com/madrobby/zepto/releases
последний релиз был в декабре, так что вы не правы.
NightmareZ
03.06.2015 16:17Попытался заюзать в проекте вместо jQuery. Отхватил кучу ошибок в jQuery-плагинах. Попытался исправить, не осилил, вернул jQuery.
IonDen Автор
03.06.2015 17:20Конечно же zepto нельзя использовать по тому же сценарию. Не так много плагинов его поддерживает. Но если например код полностью ваш, плагинов 0, то всё возможно.
NightmareZ
03.06.2015 17:40Ну просто у них написано, мол, "with a largely jQuery-compatible API", я и подумал, что можно безболезненно заменить.
artF
01.06.2015 14:53+3Это я почему злой был, потому что у меня jQuery не было.
По сути, отказываться от нее везде, и открывать велосипедный бизнес—идея не из лучших)VolCh
01.06.2015 20:19Зло — использовать универсальные библиотеки там, где достаточно нескольких строк своего кода. Особенное зло — использовать сторонние библиотекодэгде это оправдано и одновременно там, где достаточно нескольких строк своего код
Acuna
03.06.2015 15:17Лично я беру сторонние библиотеки на все случаи жизни, тщательно тормошу их, выкидываю все лишнее и получаются… Правильно, собственные библиотеки на все случаи жизни)
Rumlin
01.06.2015 14:54+8Откопал на днях старый Live CD. Запустил браузер и… всё. Практически нет сайтов, которые нормально отобразились бы. Некоторые не отображались. Для эксперимента попробовал скачать современный браузер — невозможно. Получилась ситуация курица или яйцо. Чтобы скачать современный браузер, необходимо иметь современный браузер.
Eklykti
01.06.2015 17:07+2Чтобы скачать современный браузер, необходимо иметь современный браузер.
Только что написал в консоли «w3m getfirefox.com» — и в полученном результате прекрасно угадывались и даже нажимались ссылки «Download Firefox — English (US)»Rumlin
03.06.2015 15:59Windows XP LiveCD :)
«w3m» не является внутренней или внешней
командой, исполняемой программой или пакетным файлом.
На самом деле, если проинсталировать в VM Windows 2000 даже с SP4, ситуация та же.
PsyHaSTe
02.06.2015 16:37+1А как же старый-добрый ftp? ftp.mozilla.org ftp.opera.com прекрасно открываются как через консоль, так и через эксплорер в случае Windows.
QtRoS
01.06.2015 15:20+7Мое негативное отношение к jQuery вызвано косвенными причинами — часто меня спрашивают, знаю ли я JavaScript, получают утвердительный ответ, а потом удивляются, что я даже основ jQuery не могу рассказать. Только эта подмена понятий по моему мнению (которое я не навязываю) является негативной стороной, отождествление JS и jQuery.
Zenitchik
01.06.2015 16:04+1Я больше подумываю о том, чтобы разобрать jQuery на составные части, чтобы использовать их, когда весь jQuery не нужен. Скажем, связка Deferred и Ajax — безболезненно вытаскивается.
beat
01.06.2015 17:21такая возможность была в MooTools, единственное что он теперь в полумертвом статусе
Acuna
01.06.2015 17:37-2Вот что по мне не хватает в JS (да и в jQuery косвенно) — это принудительного ввода переменных долларом ($) для отличия их от констант и функций. Пишу на PHP — там это крайне удобно! Сейчас уже, как начал переходить на jQuery, я, разумеется, названия всех переменных начинаю с $, однако много кода осталось старого, без $, что после PHP очень напрягает.
Не знаю, как в других языках обходятся без $…SelenIT2
01.06.2015 18:10+3Ой, а можно просто долларов, без переменных?.:)
Acuna
01.06.2015 18:12Ну как бы можно, да… :/
Keyten
01.06.2015 21:28+3Пользуясь случаем, спрошу: а повлияло ли изменение курса доллара на количество переменных в вашем коде?
Acuna
01.06.2015 22:41Эммм… Я, конечно, понимаю, что адаптация в любом коллективе всецело зависит от уровня искрометности юмора, поэтому это хороший повод каждому немного подняться в глазах своих коллег, однако можно сначала объяснить, что не так, а не просто минусовать? Я не вижу ничего плохого в том, чтобы учится от кого-то чему-то новому. Благодарю.
Acuna
02.06.2015 19:42Понятно. Я только одного не понимаю: это насколько нужно быть низкими людишками, чтобы стебаться (иначе не назовешь) над более слабыми у всех на глазах, вместо того, чтобы просто объяснить в чем они не правы? Неужели это так сложно? Нет начали упражняться в остроумии как будто бы решаете кому девушку в ресторан вести. А уж если все такие умные — задумайтесь, так ли это после такого? Я в шоке просто, работаю в крупном коллективе — в жизни такого не встречал! Откуда вы все тут такие собрались? Особенно к этому побуждает анонимность минусующих. Перетирал эту тему с Денискиным — сказал, что это для предотвращения взаимного минусования. Я тогда подумал «Это какой-же гнусный коллектив должен быть, чтобы до такого опуститься». Просто удивительно!
Минусуйте сколько влезет, пытайтесь таким образом хоть как-то подняться в своих глазах, мне пофиг, все-равно на комментирование это никак не влияет, однако ответ на свой вопрос я бы все-равно очень хотел бы получить.Zenitchik
02.06.2015 19:50А Вы, разве, что-то спросили? Вам влепили минус за оффтоп, потому что никому не нравится читать троллей.
Acuna
02.06.2015 19:52Да, я спросил, что всем не понравилось в моем комменте, что он вызвал такую бурю петросянства.
Zenitchik
02.06.2015 20:04Всё просто: никто не верит, что это не троллинг.
Acuna
02.06.2015 20:15Хорошо, тогда я по-другому спрошу: почему это считается троллингом?
Zenitchik
02.06.2015 20:19Потому что прикапываться к мелочам наподобие правил именования переменных в разных языках — это настолько смешно, что невозможно поверить в серьёзность.
А тем более, возводить в идеал явную экзотику на подобие PHP.Acuna
02.06.2015 20:30+1А, ну вот это я понимаю, содержательный ответ! Благодарю. Именно то, что я и хотел услышать. Извиняюсь за вспылчивость перед всеми, я действительно не усмотрел в этом троллинг. Хоть один нормальный человек нашелся, эврика!
P. S. Тема холиварненька, но PHP не экзотика, а инструмент для веба. 90% движков и проектов написано на нем. Казалось бы, почему? Сейчас появляются очень мощные разного рода *.js, однако это как гвозди унитазом забивать, честно слово! Для лендингов они подходят отлично, но писать CMS, например, или крупный проект на языке, который изначально был создан совсем для другого — это как минимум странно. Тот же PHP — он не хорош и не плох, он просто используется для другого. Как плюсы, например, используются для десктопа, так же и PHP используется для веба. Поэтому если я вижу сообщения типа «PHP отстой, пишите на нормальных языках» — я сразу понимаю, что человек реально не в курсе и просто решил выпендриться в глазах одноклассников и быть на одной волне с ними.
P. P. S. Да и для тех же лендингов тащить за собой кучу библиотек, которые реально замедляют работу пытаясь переложить все с PHP — как-то не знаю, не знаю… Какой смысл… Каждый инструмент должен использоваться по назначению.Zenitchik
02.06.2015 20:55У нас сервер на Java и толстый клиент на JavaScript.
А PHP экзотика не в плане непопулярности, а в плане своеобразности. Те же ведущие доллары в именах переменных это экзотика из той же оперы, что суффиксы типов данных в BASIC.Acuna
03.06.2015 01:17+1Простите-с, я Вас правильно понял, Java и JavaScript у Вас? Не, ну всякое бывает просто) Просто честно признаться, по роду своей деятельности мне совершенно не встречались никакие движки (CMS) не на PHP. Хотя вспомнил один, почти 10 лет назад существовала CMS'ка на Java, вроде Моцарт называлась, вышло пару версий, сейчас вроде бы он уже умер. Так я и не понял, если честно, что это было… И все, все остальные, начиная с коленочных школьных поделок и заканчивая всем известными российскими товарами широкого потребления стоимостью с машину. Лично я вижу ответ в следующем. Вот я работаю с обработкой и выводом каких-либо данных в крупном интернет-проекте. Представим, что это просто очень мощный и навороченный веб-сайт. В качестве бэкенда у меня выступает PHP, а фронтэнд — нативный JS, а в последнее время поголовно пишем на jQuery. Ну так везде, ничего нового я не открываю. Эта структура логична, так как каждый инструмент занимает свое место. Дак вот я хотел спросить, как можно это реализовать на JS, если он даже как такового ООП не имеет, а без него никуда. Есть какие-то обвертки функций, прототипы, но это не ООП, это просто имитация. И вот, например, мне нужно получить какие-то данные из какой-то БД (не обязательно Мускул, это что угодно может быть), дак вот получатель этих данных может быть каким-то объектом, который может наследовать свойства других объектов (например, один объект работает с БД, а другой объект защищает данные в запросах — то есть глобальный класс, который заведует защитой данных любых типов), эти данные надо как-то обработать (какой-то парсер или фильтр, что тоже является объектом или экземпляром какого-то объекта), а затем вывести (это может быть какой-то шаблонизатор). В свою очередь все эти объекты могут наследовать методы потомков в сложных системах, ну и не стоит забывать об областях видимости объектов и методов. Все, что я перечислил — это обычная начинка любой мало-мальски уважающей себя CMS. Это я еще в паттерны не углублялся, мы их не часто пользуем, честно скажу. Дак вот как такое можно исполнить на JS, ведь он же для другого, он для свистелок-перделок же (при всем моем уважении к нему, сам занимаюсь фронтэндом на нем, однако как я уже говорил, каждый инструмент должен выполнять ту задачу, ради которой он, собственно, и предназначался).
Zenitchik
03.06.2015 12:40+1>Дак вот я хотел спросить, как можно это реализовать на JS, если он даже как такового ООП не имеет, а без него никуда. Есть какие-то обвертки функций, прототипы, но это не ООП, это просто имитация
Это, простите шоры классового наследования. У нас, если Вы не прочитати ТОЛСТЫЙ КЛИЕНТ. Как по Вашему мы бы его написали без ООП?
Я, например, наоборот, прототипное наследование больше люблю.
Выйдите из своей норки и изучите хоть чуть-чуть друге языки кроме PHP.
gonzazoid
03.06.2015 15:45ок, пусть начнется холивар.
>Дак вот я хотел спросить, как можно это реализовать на JS, если он даже как такового ООП не имеет
Это на Java ООП нет, там класс-ориентированное программирование, а на JavaScript — как раз квинтэссенция ООП от слова объект. Просто исторически так сложилось, что ООП подразумевает под собой класс-ориентированость, а реальное ООП исторически принято называть прототипным наследованием.
Acuna
03.06.2015 01:23И насчет баксов — мы все-таки вернулись к тому, ради чего я все это и начинал) Сам против параноидальной типизации как на сях, однако Вы, собственно, что имеете против долларов?) Это удобнее, чем каждый раз писать var, но и это невероятно удобно, так как позволяет отличить переменную от константы или какого-то метода. Вот я, например, создал функцию и определил в ней три аргумента. Эти аргументы переменные. Еще навводил констант, и некоторым переменным присвоил какие-нибудь кложуры со своими аргументами. Дак вот без этих долларов все сольется же в единую кашу, и не будет понятно что вообще и где! Я просто не понимаю, как можно выступать против этого!) Это же не баг, а фича же, в прямом смысле)
IonDen Автор
03.06.2015 07:50+1В JS, а именно в ES6(ES2015), работа с переменными выведена на новый уровень, посмотрите:
var foo = "test_1"; // обычная переменная let bar = "test_2"; // переменная понимающая блочную область видимости const baz = "test_3"; // нормальная константа
Все предельно ясно я и понятно.Zenitchik
03.06.2015 12:48Этот загадочный человек выступает за префикс имени переменной, чтобы отличать его от имён других сущностей. Кажется, он очень любил бы Венгерскую нотацию, если бы таковую застал.
Acuna
05.06.2015 17:59Да, это очень даже интересно, благодарю! Осталось только реализовать области видимости данных в объектах и вообще будет сок тогда! Пока все-таки это еще даже не PHP…
Zenitchik
05.06.2015 19:51Я сейчас уже не помню подробностей, но когда венгерская нотация была популярна, в моду почему-то вошла практика обозначать префиксом тип данных. Сам автор нотации предлагал придумывать префиксы исходя из семантики.
Я лично в физических расчётах вводил префиксы, обозначающие единицы измерения — метры, секунды, Ньютоны, пр.
Сейчас от этого отошёл. Не случается писать настолько сложные процедуры, чтобы трудно было разобраться в переменных.
Да, кстати, а зачем Вам видимость данных? Языки типа JS и Lua декларируют идею: «не хочешь изменять приватные данные — не изменяй их».Acuna
09.06.2015 00:53Все до безобразия просто! Мы поддерживаем крупный проект, но некоторые его части юзеры могут деплоить сами путем написания всевозможных аддонов для каких-то существующих объектов. Мы даем им документацию того, что и куда можно встроить. И так как эти аддоны оперируют уже существующим кодом, очевидно, что нам очень не хочется, чтобы юзеры имели возможность воздействовать на то, на что их полномочия не распространяются. Например, они могут написать аддон для платежки, используя некоторые переменные какого-либо объекта, документацию которого мы им дадим, но некоторыми переменными они оперировать не смогут, так как по понятным причинам в результате работы им могут быть присвоены очень даже интимные значения, которые никак не могут быть доступны извне.
Zenitchik
03.06.2015 12:37У других же не сливается. Почему сольётся у Вас?
Это не фича, это забавная экзотическая особенность языка, не полезная и не вредная.
А мне, например, удобно было пользоваться суффиксами типов данных, вместо того, чтобы писать String, Integer и т.п. Но я же не предлагаю во все языки их вводить.
Ваши аргументы — это детский сад от нежелания изучать языки.
Про свистелки и перделки мне — занимающемуся толстым клиентом — смешно слышать.
Ещё смешнее — ваша нелюбовь к строгой типизации. Да, в вебе она не нужна, но на вебе свет клином не сошёлся. Как Вы предлагаете без строгой типизации писать десктопное приложение? Не уже ли ни разу не работали напрямую с памятю? Очень кстати бывает знать, как располагается в памяти каждый тип данных.
Zenitchik
03.06.2015 12:43Этак я тоже перестану верить, что Вы не тролль.
Acuna
05.06.2015 17:46Нет-нет, что вы! Я не то, чтобы против строгой типизации, я просто ее не люблю) Надо было точнее выразиться. Сам клепаю консольные проекты на плюсах в свободное время и сам на заре сталкивался с разного рода утечками, просто так как 90% моего времени занимает разработка на PHP, где я привык, что все приводится к нужному типу само — просто с непривычки пересаживаться сложно. Это как пересесть на механическую коробку передач в машине на автомат. Сам езжу на механике, однако постоянно думаю о том, как был бы хорош автомат, особенно в наших пробках, ибо мне есть о чем подумать, кроме как дергать коробку каждую минуту, особенно если этого можно избежать и просто наслаждаться непосредственно поездкой. Почему бы и нет?
Keyten
10.06.2015 11:49Лично я не минусовал. Просто плюсы-минусы — способ показать несогласие с вашим мнением. Не стоит так бурно на это реагировать.
Что же касается кармы (не знаю, минусовали ли туда, но, учитывая холиварность темы, скорее всего) — это способ саморегулирования сообщества. Я считаю неправильным понижать карму за несогласие с чьим-то мнением, так что постарался вам компенсировать это плюсом :).Acuna
10.06.2015 15:32Да просто реально, если даже ребенка наказывают — нужно ему объяснить, во-первых, за что, а во вторых, каким образом он должен поступать правильно, чтобы впредь такого не произошло. Но тут я просто вижу просто подлое минусование, пользуясь тем, что личность установить нельзя. Это все-равно, что воткнуть нож в спину. Примеры не сравниваются, но суть понятна, думаю.
А Вам и на том спасибо)Keyten
10.06.2015 22:56В любом сообществе, где существуют лайки / дизлайки, многие люди голосуют без объяснения причин.
Проще привыкнуть и не обращать на это внимания. Даже термин (хотя термином это язык не поворачивается назвать, но вряд ли есть более подходящее слово) есть такой: «минусующие хомячки» :)
Хотя он вроде немного о другом, но тем не менее, достаточно близок.
lurkmore.to/%D0%A5%D0%BE%D0%BC%D1%8F%D1%87%D0%BA%D0%B8
unel
01.06.2015 19:09+2Как бы то ни было, в большинстве случаев, разработчики и слыхом не слыхивали о подобных конвенциях, и в результате в их коде чрезвычайно трудно разобраться незнакомым с ним людям. Каждая попытка отредактировать такой код, влечет множество ошибок в стиле «Ох, блин, это не jQuery-объект, забыл обернуть его в $()» или «Черт, тут же не дом-элемент забыл взять его через $(..)[0]»
Ну, знаете ли, отсутствие каких-либо договорённостей в коде — это вообще плохо и не только к этому могут привести.
Также я не буду тратить время, рассуждая о размере файла и о том, насколько быстрее работают нативные методы.
Там где возможно, jQuery использует нативные методы, там где нет — заменяет своими. Это ещё один плюс jQuery. Ну и сравните:
node.addEventLictener('click', function (e) { if (elementIsNot(someSelector)) { return }; // some js code })
и
$node.on('click', someSelector, function (e) { // some js code });
не говоря уж о таких возможностях, как нейм-спейсы, кастомные события и возможность триггерить события по имени (хотя, это скорее всего уже не очень хорошая практика)
ещё плюсом у jQuery является обработка коллекций ($links.removeClass(..)) и его способность игнорировать — найден ли был элемент по селектору или нет (хотя кто-то в комментариях выше записал это в минусы)
$('#nonexistentId').remove();
vs
var node = document.getElementById('nonexistentId'); node && node.remove();
IncorrecTSW
01.06.2015 21:20Странные у вас примеры скажу я вам.
if (elementIsNot(someSelector)) { return };
Это что за невиданный зверь и с чего он в этом примере появился? + ко всему ваш «addEventLictener» меня смущает.
С удалением тоже не равносильный пример. Считать игнорирование того что выборка путая не самый хороший вариант. Если вам в конкретном случае так удобней это не значит ничего (но в данном случае я лишь повторил что писали выше).IncorrecTSW
01.06.2015 21:26+2Про «someSelector» проглядел, извиняюсь.
Но в целом ничего не изменилось.
on('click', someSelector,
Плохая практика.oWeRQ
02.06.2015 00:32Плохая практика, если вешать десятками на document ради одиноких кнопок… да даже тогда, это лучше того, что обычно наварачивают.
Считается хорошей практикой для списка из сотен элементов не вешать на каждый элемент свой обработчик. При использовании шаблонов альтернатив делегированию событий по большому счету нет.IonDen Автор
02.06.2015 07:35Мне кажется вы тут уже сравниваете теплое с мягким. Навешивание обработчиков на конкретный элемент и делегирование событий это не взаимоисключающие понятия, оба эти способа имеют свою нишу использования и нельзя говорить что одно лучше другого. Если же исключить оффтопик, то и jQuery и нативный JS позволяют без проблем использовать оба метода.
oWeRQ
02.06.2015 12:20Возможно я не совсем правильно выразился, но я не имел ввиду jQuery, ответ был про плохую практику использования делегирования, в нотации jQuery:
$el.on('click', someSelector, fn);
unel
02.06.2015 11:31Ну, скажем, делегирование — это не обязательно навешивание событий на document, можно повесить и на «главную» ноду виджета.
Также оно удобно тем, что тебе не надо заботиться о том, сколько у тебя реально кнопок внутри и не надо заморачиваться с перепривязкой событий после перерисовки содержимого этой ноды)oWeRQ
02.06.2015 12:25Полностью согласен, _бездумное_ навешивание событий на document — пожалуй, единственная плохая практика, приходящая в голову, кстати, это была одна из причин удаления метода live(хотя основная — он был костыльно реализован).
unel
02.06.2015 11:25+1Считать игнорирование того что выборка пустая не самый хороший вариант.
Ну, явное лучше неявного. Когда нам явно нужно обработать пустую выборку — это нужно будет сделать явно. А так — не хотел бы я писать на языке программирования, где someArray.filter(returnFalse) вернёт null/undefined вместо пустого массива, ну или map на пустом массиве выдаст ошибку
yeee737
02.06.2015 09:38Ох если бы.
var node = document.getElementById('nonexistentId'); node && node.remove();
Ради кроссбраузерности, приходится писать вот такое:
var node = document.getElementById('nonexistentId'); node && node.parentNode.removeChild(node);
Ну и вообще, большой плюс jQuery и любой подобной библиотеки для работы с DOM в том, что получается абстрагироваться от не самой, скажем так, изящной реализации DOM API.
Немного боли:
// vanilla var newElement = document.getElementById('someId'); newElement && newElement.parentNode.insertBefore(newElement, referenceElement); // jQuery $(newElement).insertBefore(referenceElement); // сюда же $.fn.prepend, который на vanilla будет куда монструознее.
Вообще, моё ИМХО, что нет ничего вздорного в использование готовых инструментов, вроде jQuery, Zepto, тысячи их, пока скорость не является краеугольным камнем.SelenIT2
02.06.2015 11:38Аппендить/препендить на ванилле можно еще с помощью insertAdjacentHTML, причем совместимость со старыми IE (откуда оно и пришло) получается из коробки приятным бонусом:)
Keyten
01.06.2015 21:31Наверное, вам не нужен jQuery
Вам точно не нужен jQuery!
А нужен ли вам jQuery?
10 советов как писать на JavaScript без jQuery
Сделайте третью ссылку первой :).
А что касается jQuery… Некоторое время назад интереса ради разобрал её код и написал (правда, не полностью) свой аналог.
После этого осознал, что вообще никак не нуждаюсь в jQ, т.к. могу на чистом JS написать абсолютно тоже самое, причём практически тем же количеством кода и за то же время. Тем более, что IE6 уже поддерживать не нужно.
Единственное, что напрягает, это большие имена функций. document.querySelectorAll вместо $, addEventListener вместо on…
leMar
01.06.2015 23:54+4Когда мне понадобилось писать код без jQuery, и я писал на чистом JS, я чувствовал себя эдаким «я выше всех, я лучше вас». А потом я написал обертку для querySelector. А потом для цикла по nodeList. А потом для событий. А потом я написал функцию для добавления свойств, и то что у меня вышло, пахло быдлокодом. Тогда я заглянул в исходники underscore и jquery и сделал как там. Потому что там лучше было написано. А мой helper.js тем временем рос и рос. У меня сейчас, конечно, не jquery_by_my, но к тому идет.
P.S.
Мне бы хватило билдера. Чтобы я мог выбрать, какие функции мне нужны, а какие нет (для этого jquery должен не использовать свои же собственные функции).
ababo
02.06.2015 00:52+1Тем не менее, как бы я не сочувствовала этим бедным ребятам...
Определенно я далеко не первый, кто обращает внимание...
А ещё у меня лапы болят и хвост отваливается…
spmbt
02.06.2015 02:06> Определенно я далеко не первый, кто обращает внимание...
Вы переводите от лица автора? Lea Verou? Наверное, я не первый
http://commons.wikimedia.org/wiki/File:Lea_Verou,_speaking_at_the_Fonteers_2011_conference.jpg
spmbt
02.06.2015 09:43-2Вот что сейчас заменяет довольно большой кусок манипуляций с DOM и работает быстрее, чем подход с методами (есть и варианты с jQuery-синтаксисом примерно такого же объёма, например, библ. $dom, jBone, balalaika, psQuery,… — Zepto не настолько радикально, она старается максимально покрыть jQuery). Это сокращает визуально код, чтобы не писать длинно и с повторениями на нативном. В то же время, снимается проблема из статьи — не нужно придумывать объекты-обёртки для элементов.
$e(), функция на 50 строк$e = function(g){ //===создать или использовать имеющийся элемент=== //g={el|clone,blck,elA,cl|(clAdd,clRemove),ht,cs,at,atRemove,on,revent,ap,apT,prT,bef,aft,f+fA} if(typeof g.el =='function') g.el = g.el.apply(g, g.elA); if(!g.el && g.el !==undefined && g.el !='') return g.el; //null|0|false var x, o = g.el = g.el || g.clone && typeof g.clone !='string' && g.clone.cloneNode(!0) || /\W/.test(g.clone) && (x = $q(g.clone, g.blck)) && x.cloneNode(!0) ||'DIV'; o = g.el = typeof o =='string'? /\W/.test(o) ? $q(o, g.blck) : document.createElement(o) : o; if(o){ //выполнять, если существует el или clone if(g.cl) o.className = g.cl; else{ if(g.clAdd) o.classList.add(g.clAdd); if(g.clRemove) o.classList.remove(g.clRemove);} if(g.cs) $x(o.style, g.cs); if(g.ht || g.at){ var at = g.at ||{}; if(g.ht) at.innerHTML = g.ht;} if(at) for(var i in at){ if(i=='innerHTML') o[i] = at[i]; else o.setAttribute(i, at[i]);} if(g.atRemove) for(var i in g.atRemove) o.removeAttribute(g.atRemove[i]); if(g.htT){ //подготовка шаблона if(!(typeof g.htTA =='object')) g.htTA =[g.htTA]; for(var i in g.htTA) g.htT = g.htT.replace(RegExp('\\{\\{'+ i +'\\}\\}','g'), g.htTA[i]) o.innerHTML = g.htT;} if(g.on) for(var i in g.on) if(g.on[i]) o.addEventListener(i, g.on[i],!1); if(g.revent) for(var i in g.revent) if(g.revent[i]) o.removeEventListener(i, g.revent[i],!1); if(g.ap){ //добавление нод if(g.ap instanceof Array){ for(var i in g.ap) if(g.ap[i] && i !='length') o.appendChild(g.ap[i]); }else o.appendChild(g.ap);} g.apT && g.apT.appendChild(o); g.prT && (g.prT.firstChild ? g.prT.insertBefore(o, g.prT.firstChild) : g.prT.appendChild(o) ); g.bef && g.bef.parentNode.insertBefore(o, g.bef); g.aft && (g.aft.nextSibling ? g.aft.parentNode.insertBefore(o, g.aft.nextSibling) : g.aft.parentNode.appendChild(o) ); g.remove && g.remove.parentNode.removeChild(g.remove); if(typeof g.f =='function') g.f.apply(g, g.fA); //this - это g } return o; } ,$q = function(q, f){ return (f||document).querySelector(q);} ,$qA = function(q, f){ return (f||document).querySelectorAll(q);}
gonzazoid
02.06.2015 16:50ну вы в двух словах хоть опишите — что оно делает? Непонятно сходу — стоит раскуривать, нет?
spmbt
03.06.2015 16:32А разве по коду не видно? Создаёт DOM-элементы, меняет их атрибуты, стили и обработчики событий, выполняет условные действия (если элемент есть (или нет), то делать), прицепляет (или перецепляет) элемент к другим, удаляет. Пример использования (более 100 вызовов) — в HabrAjax (строка 700 или искать по "$e ="), появилось там из-за нежелания вкручивать jQuery, работает более 2 лет и постепенно обрастает практически полезными функциями. С небольшой доработкой делается способным для работы с IE8.
Из нерешённых вопросов — не полностью выяснена, какой должна быть логика условных операций, чтобы она была и очевидной, и покрывающей максимум практических случаев. Например, логика «если элемента нет, то создать» в имеющейся функции существует и работает, если g.el === undefined или "", но не работает на null|0|false. Столь тонкое различие, насколько помню, ни разу не было использовано. Надо ли оно?
Да, и там ещё нужна такая функция:
var $x = function(el, h){if(h) for(var i in h) el[i] = h[i]; return el;}, //===extend===
Затем, добавляется несколько функций категории traversing, работа с Event, и замена — довольно полноценна (если не считать ещё операций с коллекциями — их, наверное, закодировать можно, но лучше в отдельную функцию, как в $$()).
KeepYourMind
02.06.2015 11:14+1Абстрагироваться от DOM можно и другим способом — через Virtual DOM.
Наример, используя React :-)
mihmig
02.06.2015 16:14Вот смотрите: сейчас Хром (движок V8 если не ошибаюсь) берёт JS-код и «по-умному» его компилирует в «рантайме», да так, что работает быстрее чем байткод Java.
Так почему бы уже это сгенерированный код не вставить в сам хром, например:
встречает браузер ссылку в head на cdn....jquery.min.js и раз — не парсит его, интерпретируя. А сразу переходы на СКОМИПЛИРОВАННЫЙ код — всё летает.gonzazoid
02.06.2015 16:44ну так если оно с CDN и закешировано — то почему вы решили что оно именно так и не работает?
0xy
08.06.2015 16:41Самый короткий вариант имитации jQuery
var $ = document.querySelector.bind(document); Element.prototype.on = Element.prototype.addEventListener; // usage $('#foo').on('click', function(){ ... });
DeXPeriX
JQuery — инструмент. И инструмент неплохой. Зачем отказываться от него вообще везде, если есть задачи, для которых эта библиотека действительно хороша?
IonDen Автор
Сегодня я уже не уверен в этом тезисе. Если отказаться от IE9 и ниже, все анимации перевести на CSS, то я больше не могу придумать ни одной задачи, которую было бы сложно реализовать без использования jQuery. Возможно отчасти это просто инерция мышления, зачем менять если работает?
DeXPeriX
Например, галерея изображений. Искал с возможностью пролистывания, на любое количество картинок. На CSS ничего толкового так и не нашёл — либо совсем слабенько, либо тяжёлый CSS код с большим количеством констант для абсолютного позиционирования. На чистом JS писал — теряется много «фишечек», которые реализовывать муторно.
Ещё могу предположить различные онлайн графические редакторы — также проще будет реализовать с использованием JQuery.
WaveCut
для этой задачи (галерея) не нужен jquery ну вообще никак. ЦСС транзиции и парочка обработок кликов со сменой позиции… Вы тут скорее обосновываете джаваскрипт в принципе! :)
mihmig
ЦСС транзиции, «вирусные дефиниции»… эх…
WaveCut
"ня важна!" :)
oWeRQ
> Ещё могу предположить различные онлайн графические редакторы — также проще будет реализовать с использованием JQuery.
jQuery в основном для работы с DOM, для canvas в нем вообще нет инструметов.
SelenIT2
Предположу, что речь про всякие «кропалки-ресайзилки» для картинок (рамка-выделялка с квадратиками-тягалками и т.п.).
qRoC
В последнее время сравниваю jQuery с WordPress — считаю их инструментами для которых писать ничего не нужно ибо всё написано до вас, но вот когда готового решения нет, то начинается тихий ужас. Оба решения держатся из-за базы плагинов.
Немного непонятно какие «фишечки» может резать чистый js?
На самом деле без учёта базы плагинов трудно найти нишу для jQuery.
* Кроссбраузерность? Есть полифиллы.
* Ajax? Есть fetch.
* Анимации? Есть CSS.
* Работа с DOM? Получается каша из кода. Лучше использовать другие библиотеки.
DeXPeriX
Ниже уже отвечено, что всё, что есть в JQuery можно реализовать в чистом JS. Вопрос — зачем велосипедить. Имел ввиду как раз базу плагинов, там есть много чего.
Zenitchik
Вы же не хотите сказать, что ни разу не написали какой-нибудь плагин для jQuery?
qRoC
Писал, получалась каша из логики и работы с DOM, попытки разделить приводили к раздуванию кода.
nazarpc
Напишите спагетти из нескольких AJAX вызовов и сравните с вариантом на jQuery.
И да, всё еще остается много специфичных вещей, которые работают по разному в разных браузерах.
Зачем каждый раз писать одно и то же, если можно просто дёргнуть метод?
К тому же jQuery весьма небольшая библиотека, а в 3.0 отрезается поддержка старых браузеров.
Ну и наконец, отказаться-то можно, но тогда вы закончите jQuery-like велосипедом, который наверняка будет медленнее и проблематичнее, да ещё и его синтаксис не будет знаком такому количеству людей.
Если вы используете jQuery исключительно вместо document.querySelector() — то это вовсе не значит, что на этом функционал библиотеки заканчивается.
oWeRQ
> Напишите спагетти из нескольких AJAX вызовов и сравните с вариантом на jQuery.
Через fetch же.
> Если вы используете jQuery исключительно вместо document.querySelector() — то это вовсе не значит, что на этом функционал библиотеки заканчивается.
Сейчас большая часть фукционала появилась в стандарте(для поддержки можно использовать polyfill'ы), нет только цепочек вызовов, но ради них слишком большой оверхед.
NightmareZ
jQuery 3.0?
nazarpc
Да, она сейчас в активной разработке, там более строгое отношения к входным параметрам, поэтому далеко не весь старый код запустится без изменений.
nazarpc
Реализовать можно вообще всё, ибо jQuery написана на JS, не наоборот, вот только смысл?
Shlom
С радостью откажусь, если можно будет получить функционал DataTables без его использования. Пока даже близких способов реализации без JQuery не нашел.
mihmig
Скажите, а есть альтернативы DataTables? С более удобной документацией и примерами?
Нет, я конечно разобрался и сделал, но возникло такое ощущение, что всячески намекают на платную подержку…
Shlom
Когда искал решение видел много похожих плагинов. DataTables оказался самым удобным, гибким и наиболее понятным из всех, что попробовал.
dom1n1k
Вот кстати с CSS-анимациями вопрос спорный. Да, какие-то очень простые анимашки делаются там хорошо.
Но как только попадается что-то мало-мальски нетривиальное, то понимаешь, что на CSS это реализовать будет очень муторно и громоздко, а иногда и вовсе невозможно. А потом ещё поддерживать и модернизировать этот ад неудобно.
SelenIT2
Кстати, да. Особенно когда нужно анимировать компоненты
transform
по отдельности…VolCh
Часто сталкивался с тем, что эта проблема возникает, когда пишет код недостаточно квалифицированный специалист, например бэкендер типа меня :)
aTei
Космический корабль через анимации запускаете? :)
fenrirgray
Отказаться от IE9 — зачастую еще IE8 нужно поддерживать, а вы уже от IE9 отказываетест ==
IonDen Автор
В статье же написано, что все это не касается тех людей, которые вынуждены поддерживать старые IE.
fenrirgray
Я читал. Просто завидую.
Aingis
Даже в IE8 есть querySelector. В отличие, как ни странно, от getElementsByClassName.
pandas
Это высказывание актуально для очень многих библиотек, фреймворков и языков программирования. Я полностью согласен, что решающий конкретную задачу инструмент глупо было бы не использовать. И для каждого случая есть свой инструмент. Тоже и для ангуляра актуально, и для Руби, и даже для внутреннего языка 1С. Для своих задач — более чем. А вот пихать везде тот же jquery, не думая головой — это вот плохо :-)