Коли використовувати ванільний JavaScript проти jQuery?


238

Я помітив під час моніторингу / спроби відповісти на поширені питання jQuery, що існують певні практики використання JavaScript, а не jQuery, які насправді дозволяють писати менше і робити ... ну таку ж суму. А також може принести переваги продуктивності.

Конкретний приклад

$(this) проти this

Всередині події клацання, що посилається на ідентифікатор натиснутих об'єктів

jQuery

$(this).attr("id");

Javascript

this.id;

Чи є інші подібні звичаї? Де певні операції з Javascript можна було зробити простіше, не вводячи jQuery в суміш. Або це рідкісний випадок? ("ярлик" jQuery фактично вимагає більше коду)

EDIT: Хоча я ціную відповіді щодо продуктивності jQuery та звичайного javascript, я фактично шукаю набагато більш кількісні відповіді. Під час використання jQuery , випадки, коли насправді краще (читабельність / компактність) використовувати звичайний JavaScript замість цього $(). Окрім прикладу, який я наводив у своєму оригінальному запитанні.


Я не впевнений, що розумію питання. Ви шукали думки щодо переваг використання бібліотечного коду, або шукали додаткові не-jQuery сумісні методи перехресного браузера this.id?
користувач113716

1
з відповідей здається, що всі сприймають це питання як філософське, тому що я задумав його бути дуже кількісним, так як майже скласти список випадків, як той, який я окреслив, які є звичайними (зловмисними) практиками.
jondavidjohn


Відповіді:


207
  • this.id (як ти знаєш)
  • this.value(для більшості типів вводу. Єдині проблеми, які я знаю, - це IE, коли у елементів <select>немає valueвластивостей, встановлених на його <option>елементах, або радіовведення в Safari.)
  • this.className щоб отримати або встановити весь властивість "класу"
  • this.selectedIndexпроти a, <select>щоб отримати вибраний індекс
  • this.optionsпроти а, <select>щоб отримати список <option>елементів
  • this.textпроти, <option>щоб отримати його текстовий вміст
  • this.rowsпроти, <table>щоб отримати колекцію <tr>елементів
  • this.cellsпроти a, <tr>щоб отримати його клітини (td & th)
  • this.parentNode отримати безпосереднього батька
  • this.checkedщоб отримати перевірений стан checkbox Подяки @Tim Down
  • this.selectedщоб отримати вибраний стан option Подяки @Tim Down
  • this.disabledщоб отримати статус відключеного input Подяки @Tim Down
  • this.readOnlyщоб отримати стан readOnly завдяки input Подяки @Tim Down
  • this.hrefпроти <a>елемента, щоб отримати йогоhref
  • this.hostnameпроти <a>елемента, щоб отримати область йогоhref
  • this.pathnameпроти <a>елемента, щоб отримати його шляхhref
  • this.searchпроти <a>елемента, щоб отримати його рядок запитуhref
  • this.src проти елемента, де допустимо мати а src

... Я думаю, ви зрозуміли ідею.

Будуть часи, коли продуктивність має вирішальне значення. Наприклад, якщо ви виконуєте щось у циклі багато разів, ви можете захопити jQuery.

Загалом ви можете замінити:

$(el).attr('someName');

з:

Зверху було погано сформульовано. getAttributeне є заміною, але вона отримує значення атрибута, надісланого з сервера, і його відповідне setAttributeвстановить його. Необхідна в деяких випадках.

Висловлювання, подані нижче, накривали це. Дивіться цю відповідь для кращого лікування.

el.getAttribute('someName');

... для прямого доступу до атрибуту. Зауважте, що атрибути не збігаються з властивостями (хоча вони іноді відображають один одного). Звичайно, setAttributeтеж є.

Скажімо, у вас виникла ситуація, коли ви отримали сторінку, де вам потрібно розгортати всі теги певного типу. Це швидко і просто за допомогою jQuery:

$('span').unwrap();  // unwrap all span elements

Але якщо їх багато, можливо, ви захочете зробити трохи рідного API DOM:

var spans = document.getElementsByTagName('span');

while( spans[0] ) {
    var parent = spans[0].parentNode;
    while( spans[0].firstChild ) {
        parent.insertBefore( spans[0].firstChild, spans[0]);
    }
    parent.removeChild( spans[0] );
}

Цей код досить короткий, він працює краще, ніж версія jQuery, і його можна легко перетворити на функцію багаторазового використання у вашій персональній бібліотеці.

Може здатися, що у мене є нескінченний цикл із зовнішньою whileпричиною while(spans[0]), але тому, що ми маємо справу зі "живим списком", він оновлюється, коли ми робимо parent.removeChild(span[0]);. Це досить чудова функція, яку ми не вистачаємо, працюючи з масивом (або з об’єктом, схожим на масив).


2
приємно ... тому в основному він обертається навколо цього ключового слова, не забуваючи перетворюватися в об’єкт jQuery.
jondavidjohn

1
@jondavidjohn: Ну, є деякі виправлення, які є приємними в деяких випадках, наприклад, this.valueде у певних випадках є декілька химер браузера. Все залежить від вашої потреби. Існує багато приємних прийомів, які без jQuery прості, особливо коли продуктивність має вирішальне значення. Я спробую придумати більше.
користувач113716

3
Я збирався написати відповідь, але замість цього я додам ваші пропозиції. Взагалі, attr()масово зловживають. Якщо ви маєте справу лише з одним елементом, то вам рідко знадобиться attr(). Двоє з моїх улюблених плутанини навколо checkedмайна прапорців (всі види містичних заклинань навколо цього один: $(this).attr("checked", "checked"), і $(this).is(":checked")т.д.) і подібним чином selectedвластивості <option>елементів.
Тім Даун

1
Aaargh, @patrick, noooo: ти рекомендував getAttribute(). Ви майже ніколи не потребуєте : він порушений в IE, не завжди відображає поточний стан і все одно не те, що робить jQuery. Просто використовуйте властивості. stackoverflow.com/questions/4456231/…
Tim Down

1
Я використовував JS так довго, і я не знав про className, thx.
IAdapter

60

Правильна відповідь полягає в тому, що ви завжди будете штрафувати за ефективність, використовуючи jQuery замість "звичайного старого" рідного JavaScript. Це тому, що jQuery - це бібліотека JavaScript. Це не нова фантастична нова версія JavaScript.

Причина того, що jQuery є потужним, полягає в тому, що він створює надмірно важкі речі в умовах перехресного веб-переглядача (AJAX - один з найкращих прикладів) і згладжує невідповідності між безліччю доступних браузерів і забезпечує послідовний API. Це також легко полегшує такі поняття, як ланцюжок, мається на увазі ітерація тощо, щоб спростити спільну роботу над групами елементів.

Навчання jQuery не замінює вивчення JavaScript. Ви повинні мати міцну основу в останньому, щоб ви цілком оцінили те, що знання перших полегшує вам.

- Відредаговано, щоб охопити коментарі -

Оскільки коментарі швидко зазначають (і я згоден на 100%), наведені вище твердження відносяться до коду порівняльного аналізу. "Народне" рішення JavaScript (припустимо, що воно добре написано) випереджає рішення jQuery, яке виконує те саме, що майже у кожному випадку (я б хотів побачити приклад інакше). jQuery прискорює час розробки, що є значною перевагою, яку я не маю на увазі знецінювати. Це полегшує читання, просте кодування, що більше, ніж деякі розробники здатні створити самостійно.

На мою думку, відповідь залежить від того, що ви намагаєтесь досягти. Якщо, як я вважав, виходячи з ваших посилань на переваги від продуктивності, ви домагаєтеся найкращого можливого швидкості подання заявки, то за допомогою jQuery вводиться накладні витрати кожного разу, коли ви телефонуєте $(). Якщо ви збираєтеся читати, узгоджено, перехресно підтримувати сумісність браузера тощо, то, безумовно, є причини надати перевагу jQuery над "рідним" JavaScript.


8
Я хотів би побачити приклад ситуації, коли jQuery може перевершити реалізацію в чистому JS. Незалежно від того, що ви робите, якщо ви використовуєте jQuery (або будь-яку іншу бібліотеку для цього), у вас є функція накладних витрат, що неминуче. Немає можливості відійти від (хоча і) другорядного накладного покриття, що генерується при виклику $(). Якщо ви не телефонуєте, ви економите час.
gddc

16
Погано написане домашнє рішення, ймовірно, буде повільніше. Команда jQuery виконала кілька високоефективних JavaScript у пакеті. Дивіться відповідь @ фрілансера.
Стівен

3
Погано написане рішення завжди буде погано написаним рішенням, і це не вина мови. Це не змінює того факту, що бібліотека матиме накладні витрати, щоб «рідна» функція могла уникнути, якщо добре продумати.
gddc

11
@gddc Я думаю, що найкращий приклад, коли jQuery "перевершує" (читати поза полем еталону) чистий JS - це скорочення робочого часу (це велике значення для бізнесу) та спрощення експериментів
Бен

13
Все, що ви написали, є правдою, але ви залишили те, що @Ben зазначає вище. jQuery робить розробника швидшим і надійнішим. Дивіться цю реалізацію KillClass (), про яку я писав багато років тому і якою сильно користувався. Знаєш, що? Він порушений для певних крайових випадків. Поганий код - це поганий код, а неправильний - неправильний код, але використання jQuery часто змушує розробника писати кращий і правильніший код. Більшість часу комп’ютери досить швидкі; саме розробники потребують допомоги.
Фрогз

38

Є рамка під назвою ... о, здогадайтесь, що? Vanilla JS. Сподіваюсь, ви отримаєте жарт ...: D Він жертвує розбірливістю коду для продуктивності ... Порівнюючи його jQueryнижче, ви можете побачити, що пошук DOMелемента на IDмайже на 35 разів швидше. :)

Тож якщо ви хочете виступу, то краще спробуйте Vanilla JS та зробіть власні висновки. Можливо, ви не відчуєте JavaScript, який підвішує GUI браузера / блокує потік інтерфейсу користувача під час інтенсивного коду, як усередині forциклу.

Vanilla JS - це швидка, легка, багатоплатформна система для створення неймовірних, потужних програм JavaScript.

На їх домашній сторінці є кілька порівнянь:

введіть тут опис зображення


1
@ Леніел Макафері О, людина, мені сподобалась ця відповідь! Я не розумів, що продуктивність між ваніллю та іншими рамками може змінити таку зміну! У будь-якому випадку Зал слави за цю відповідь !! PS: Ви також зробили веб-сайт?
Стів

17

Відповідь вже прийнято, але я вважаю, що жодна відповідь, набрана тут безпосередньо, не може бути вичерпною у її списку власних методів / атрибутів JavaScript, що практично гарантує підтримку крос-браузера. З цього приводу я можу перенаправити вас на quirksmode:

http://www.quirksmode.org/compatibility.html

Це, мабуть, найбільш повний перелік того, що працює, а що не працює в будь-якому браузері. Зверніть особливу увагу на розділ DOM. Це читати багато, але сенс полягає не в тому, щоб прочитати все це, а використовувати його в якості посилання.

Коли я почав серйозно писати веб-додатки, я роздрукував усі таблиці DOM і повісив їх на стіну, щоб я з першого погляду знав, що безпечно у використанні та що вимагає хак. У ці дні я просто гуглю щось подібне, quirksmode parentNode compatibilityколи у мене є сумніви.

Як і все інше, судження - це переважно питання досвіду. Я б не рекомендував вам читати весь сайт і запам'ятовувати всі проблеми, щоб з’ясувати, коли використовувати jQuery і коли просто використовувати JS. Тільки знайте про список. Шукати досить просто. З часом ви виробите інстинкт, коли простий JS кращий.


PS: У ППК (автора сайту) також є дуже приємна книга, яку я рекомендую прочитати


14

Коли:

  1. ви знаєте, що існує незмінна підтримка крос-браузера для того, що ви робите, і
  2. це не значно більше коду набрати, і
  3. він не є менш читабельним, і
  4. ви досить впевнені, що jQuery не вибиратиме різні реалізації на основі браузера для досягнення кращої продуктивності, тоді:

використовувати JavaScript. В іншому випадку використовуйте jQuery (якщо можете).

Редагувати : Ця відповідь застосовується як при виборі використання jQuery загалом, так і проти виходу з нього, а також при виборі ванільного JS всередині jQuery. Вибір між attr('id')і .idнахиляється на користь JS, при виборі між по removeClass('foo')порівнянні .className = .className.replace( new Regexp("(?:^|\\s+)"+foo+"(?:\\s+|$)",'g'), '' )нахиляється на користь JQuery.


3
Я думаю, що ОП має намір використовувати jQuery, але задається питанням, де і коли використовувати рідний JavaScript всередині його методів jQuery.
Стівен

.classList.remove('foo')Здається, працює в нових браузерах
Тиїло

3
@Tyilo classList.remove є частиною HTML5 ClassList API, не реалізований в IE9, наприклад caniuse.com/#feat=classlist
Corbacho

13

Відповіді інших були зосереджені на широкому питанні "jQuery vs plain JS". Судячи з вашої ОП, я думаю, що ви просто задавались питанням, коли краще використовувати ванільний JS, якщо ви вже вирішили використовувати jQuery. Ваш приклад є прекрасним прикладом, коли вам слід використовувати ванільний JS:

$(this).attr('id');

Це і повільніше і (на мою думку) менш читабельним, ніж:

this.id.

Це повільніше, оскільки вам доведеться закручувати новий JS-об’єкт лише для отримання атрибута способом jQuery. Тепер, якщо ви будете використовувати $(this)для виконання інших операцій, то будь-якими способами зберігайте цей об'єкт jQuery у змінній та оперуйте ним. Однак я зіткнувся з багатьма ситуаціями, коли мені просто потрібен атрибут з елемента (наприклад, idабо src).

Чи є інші подібні звичаї? Де певні операції з Javascript можна було зробити простіше, не вводячи jQuery в суміш. Або це рідкісний випадок? ("ярлик" jQuery фактично вимагає більше коду)

Я думаю, що найпоширеніший випадок - це той, який ви описуєте у своєму дописі; люди, що загортаються $(this)в об’єкт jQuery без необхідності. Я бачу це найчастіше з idі value(замість цього використовую $(this).val()).

Редагувати: Ось стаття, яка пояснює, чому використання jQuery у цьому attr()випадку повільніше. Сповідь: викрав його з тегів wiki, але я думаю, що це варто згадати для запитання.

Знову редагуйте: враховуючи читабельність / ефективність наслідків простого доступу до атрибутів, я б сказав, що хороше правило, мабуть, намагається використовувати, this.<attributename>коли це можливо. Напевно, є деякі випадки, коли це не спрацює через невідповідності браузера, але, мабуть, краще спробувати це спочатку і повернутися до jQuery, якщо він не працює.


га, дякую, що прочитали запитання;) ... тож це ширше виняток?
jondavidjohn

@jondavidjohn: Чесно кажучи, я не вагаюся телефонувати. Я думаю, що так, зазвичай ви користуєтеся jQuery через проблеми з перехресними веб-переглядачами. Є й інші приклади, наприклад this.style.display = 'none'. Це краще, ніж $(this).hide()? Я б заперечував, що останній читабельніше, але перший, швидше за все, швидший. Не завадить зробити експерименти самостійно, щоб побачити, чи будуть діяти певні дії у веб-переглядачах без jQuery. Це, як правило, те, що я роблю, перш ніж загортати елемент в об’єкт jQuery для виконання операції.
Ендрю Вітакер

10

Якщо вас найбільше турбує продуктивність, ваш головний приклад вдаряє нігтем по голові. Викликати jQuery без зайвих чи надмірних умов, IMHO є другою основною причиною повільної продуктивності (перша - поганий обхід DOM).

Це насправді не приклад того, що ви шукаєте, але я бачу це так часто, що в ньому згадується: Один з найкращих способів прискорити виконання сценаріїв jQuery - це кешування об’єктів jQuery та / або використання ланцюжка:

// poor
$(this).animate({'opacity':'0'}, function() { $(this).remove(); });

// excellent
var element = $(this);
element.animate({'opacity':'0'}, function() { element.remove(); });

// poor
$('.something').load('url');
$('.something').show();

// excellent
var something = $('#container').children('p.something');
something.load('url').show();

що цікаво ... чи справді це розділення варіантів дії та дії фактично призводить до підвищення продуктивності? або просто дозволяє дію виконати самостійно (зробивши її менш обтяженою, я здогадуюсь ...)
jondavidjohn

1
Це, безумовно, призводить до підвищення продуктивності, але тільки якщо ви повторно використовуєте вибраний елемент. Отже, в останньому випадку var somethingмені не потрібно було кешувати об’єкт jQuery (оскільки я використовував ланцюжок), але я це все одно роблю за звичкою.
Стівен

2
З іншого боку, візьміть той самий приклад. Виклик $('.something')двічі означає, що jQuery повинен пройти DOM двічі, шукаючи всі елементи за допомогою цього селектора.
Стівен

2
У випадку першого прикладу кешування $(this)зменшує виклики до функції jQuery. Це дасть вам найбільший прибуток у циклі циклу.
Стівен

2
@Alnitak Зауважте, що elementдорівнює $(this). Це не містить декількох елементів.
Стівен

8

Я виявив, що між JS та JQ, безумовно, є перекриття. Код, який ви показали, є хорошим прикладом цього. Чесно кажучи, найкраща причина використовувати JQ над JS - це просто сумісність браузера. Я завжди схиляюся до JQ, навіть якщо можу щось досягти в JS.


8
Було б цікаво, якби не було перекриття, тому що JQuery - це JavaScript.
симон

6

Це моя особиста думка, але так як jQuery все одно є JavaScript, я думаю, що теоретично він не може працювати краще, ніж ванільний JS.

Але практично це може бути краще, ніж рукописний JS, оскільки рукописний код може бути не настільки ефективним, як jQuery.

Підсумок - для менших речей я, як правило, використовую ванільну JS, для інтенсивних проектів JS я люблю використовувати jQuery, а не винаходити колесо - це також більш продуктивно.


1
Є чимало прикладів, коли бібліотеки перевершують ванільну JS. Багато вбудованих прототипів методів JS погано написані, виявляється.
Статистика навчання на прикладі

3

Список живих властивостей першої відповіді thisяк елемента DOM є досить повним.

Можливо, вам також буде цікаво знати деяких інших.

Коли це документ:

  • this.formsщоб отримати HTMLCollectionпоточну форму документів,
  • this.anchorsщоб отримати HTMLCollectionз усіх HTMLAnchorElementsз nameтим набором,
  • this.linksщоб отримати HTMLCollectionвсі HTMLAnchorElementз hrefналаштування,
  • this.imagesщоб отримати HTMLCollectionз усіх HTMLImageElements
  • те ж саме із застарілими аплетами, як this.applets

Працюючи з document.forms, document.forms[formNameOrId]отримує так звану або ідентифіковану форму.

Коли це форма:

  • this[inputNameOrId] щоб отримати так зване або ідентифіковане поле

Коли це поле форми:

  • this.type щоб отримати тип поля

Під час навчання селекторів jQuery ми часто пропускаємо вивчення вже наявних властивостей елементів HTML, до яких так швидко отримати доступ.


Вказані вами властивості визначені в специфікації HTML DOM Level 2 та широко підтримуються. document.embedsа document.pluginsтакож широко підтримуються (DOM 0). document.scriptsце також зручна колекція, визначена в специфікації HTML5 та широко підтримується (і Firefox 9+ ).
Роб Ш

@Robw Отже, зараз список може бути повним, безумовно, корисним та швидким. Спасибі;)
lib3d

2

Як завжди я запізнююсь на цю вечірку.

Не додаткова функціональність змусила мене вирішити використовувати jQuery настільки ж привабливо, як це було. Адже ніщо не заважає писати власні функції.

Справа в тому, що було так багато хитрощів, як навчитися змінювати DOM, щоб уникнути витоку пам'яті (я говорю про вас, IE). Мати один центральний ресурс, який керував усіма цими питаннями для мене, написаними людьми, які були набагато кращими кодерами JS, ніж я коли-небудь буду, що постійно переглядали, переглядали та перевіряли, що Бог посилав.

Я думаю, що цей тип підпадає під аргумент крос-браузера підтримки / абстракції.

І звичайно, jQuery не виключає використання прямого JS, коли вам це було потрібно. Я завжди відчував, що ці два ніби працюють безперебійно.

Звичайно, якщо ваш браузер не підтримується jQuery або ви підтримуєте середовище низького рівня (старіший телефон?), То великий файл .js може бути проблемою. Пам'ятаєте, коли jQuery був крихітним?

Але зазвичай різниця в продуктивності не викликає занепокоєння. Це має бути досить швидко. Коли Gigahertz процесорних циклів збирається витрачати щосекунди, я більше переймаюся роботою своїх кодерів, єдиних ресурсів розвитку, які не подвоюються за потужністю кожні 18 місяців.

Це сказав, що я зараз розглядаю проблеми доступності, і, мабуть, .innerHTML - це трохи ні, ні з цим. jQuery звичайно залежить від .innerHTML, тому зараз я шукаю основу, яка буде залежати від дозволених дещо виснажливих методів. І я можу уявити, що такий фреймворк буде працювати повільніше, ніж jQuery, але поки він працює досить добре, я буду щасливий.


2

Ось нетехнічна відповідь - багато завдань можуть не дозволяти певні бібліотеки, наприклад, jQuery.

Насправді, Google фактично не дозволяє jQuery ні в коді (ні в React, оскільки він належить Facebook), про який ви, можливо, не знали, поки інтерв'юер не сказав: "Вибачте, але ви не можете використовувати jQuery, це не ввімкнено затверджений список у корпорації XYZ ". Ванільний JavaScript працює абсолютно скрізь, кожного разу і ніколи не доставить вам цієї проблеми. Якщо ви покладаєтесь на бібліотеку, то ви отримуєте швидкість і легкість, але втрачаєте універсальність.

Крім того, якщо говорити про інтерв'ю, інший мінус полягає в тому, що якщо ви скажете, що вам потрібно використовувати бібліотеку для вирішення проблеми JavaScript під час тестування коду, це трапляється так, як ви насправді не розумієте проблему, яка виглядає якось погано. Тоді якщо ви вирішите це в сирому ванільному JavaScript, він демонструє, що ви насправді розумієте і можете вирішити кожну частину будь-якої проблеми, яку вони кинуть перед вами.


1

$(this)відрізняється від this:

Використовуючи, $(this)ви забезпечуєте передачу прототипу jQuery на об'єкт.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.