Відмінності між поданням та підкресленням [закрито]


1602

Чому хтось віддасть перевагу бібліотеці утиліт lodash.js або underscore.js над іншою?

Здається, Лодаш є заміною для підкреслення, остання вже довша.

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


2
Ви можете ознайомитись із деякими екранами про лодаш, які пов’язані на його сторінці github. Особисто я використовував underscore.js, але більше, тому що з цього я почав і, як ви кажете, довше.
Джек

26
lodashі underscoreзнаходяться під злиттям нитки в даний час
zangw

Відповіді:


2022

Я створив Lo-Dash для забезпечення більш послідовної підтримки ітерації міжсередовищ для масивів, рядків, об'єктів та argumentsоб'єктів 1 . З тих пір вона стала сукупністю Underscore, що забезпечує більш послідовну поведінку API, більше функцій (наприклад, підтримка AMD, глибокий клон та глибоке злиття), більш ретельну документацію та тестові одиниці (тести, які виконуються в Node, Ringo, Rhino, Narwhal, PhantomJS та веб-переглядачі), краща загальна продуктивність та оптимізація для великих ітерацій масивів / об’єктів та більша гнучкість у користувацьких складах утилітах попередньої компіляції шаблонів.

Оскільки Lo-тир оновлюється частіше , ніж підкреслення lodash underscoreзбірка забезпечуються , щоб забезпечити сумісність з останньою версією стабільного підкреслення.

Якось мені навіть дали доступ до підкреслення, частково тому, що Lo-Dash відповідає за підняття понад 30 питань; виправлення посадкових помилок, нові функції та посилення перф у програмі Underscore v1.4.x +.

Крім того, є щонайменше 3 котлопластини для котлів, які включають Lo-Dash за замовчуванням, і Lo-Dash зараз згадується в офіційній документації Backbone .

Перегляньте повідомлення Кіта Кембриджа: Скажіть "Привіт" Ло-Даш , щоб отримати більш глибоку інформацію про відмінності між Ло-Даш та Підкресленням.

Виноски:

  1. Підкреслення має непослідовну підтримку масивів, рядків, об'єктів та argumentsоб’єктів. У новіших браузерах методи підкреслення ігнорують отвори в масивах , методи "Об'єкти" ітератують argumentsоб'єкти, рядки трактуються як масиви, а методи правильно ітератують функції (ігноруючи їх властивість "прототип") та об'єкти (ітерація тіньових властивостей, таких як "toString" і "valueOf"), тоді як у старих браузерах вони не будуть. Також методи підкреслення, як _.cloneзбереження отворів у масивах, а інші, як _.flattenні.

174
@Brian - Під час розробки Lo-Dash я продовжував задавати питання "Що може хтось вказувати на Lo-Dash як негатив у порівнянні з підкресленням?" а потім звертатися до них. Ось чому я покращив документацію, додав власні збірки та зробив джерело більш читабельним.
Джон-Девід Далтон

10
Я дуже спокушаюсь розмістити деякі орієнтири, але це може стати нудним. Досить сказати, що кожен тест, який я запускав, довів, що Lo-Dash є швидшим ( В багатьох випадках набагато швидшим), ніж підкреслення.
Віль Мур III

186
Я люблю lo-dash і використовую його, тому, будь ласка, не думайте, що я б'юся, але чому б не зробити внесок у підкреслення замість створення нової бібліотеки?
Ксанакс

133
@Xananax - перевірте нитку коментарів: github.com/jashkenas/underscore/commit/… - це може відповісти на це запитання.
Роб Грант

41
Чи були вкладені будь-які зусилля, щоб об'єднати лодаш у підкреслення?
вуличне

186

Lo-Dash натхненний підкресленням, але сьогодні це чудове рішення. Ви можете створювати власні збірки , мати більш високу продуктивність , підтримувати AMD та чудові додаткові функції . Перевірте цей показник Lo-Dash vs Underscore на jsperf і .. цей дивовижний пост про lo-dash :

Однією з найкорисніших функцій під час роботи з колекціями є скорочений синтаксис:

var characters = [
  { 'name': 'barney', 'age': 36, 'blocked': false },
  { 'name': 'fred',   'age': 40, 'blocked': true }
];

// using "_.filter" callback shorthand
_.filter(characters, { 'age': 36 });

// using underscore
_.filter(characters, function(character) { return character.age === 36; } );

// → [{ 'name': 'barney', 'age': 36, 'blocked': false }]

(взяті з документах lodash )


1
Посилання на блог Kit Cambridge є дуже інформативним.
Брайан М. Хант

Я думаю, що це неправильно (приклад пласку). Починаючи з останнього оновлення 1.8.3, ви можете використовувати вищипування так само, як лодаш. так чи інакше для попередніх версій, я не думаю, що підкреслення може виявити функцію, яка є тією ж картою (ваш приклад підкреслення здається функцією карти)
alexserver

7
filterособливість у підкресленні з 2012 року github.com/jashkenas/underscore/isissue/648 (її звуть where)
Muhammad Hewedy

Я отримую помилку 500 за посиланням Lo-Dash vs Underscore
Hylle

86

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

Ось поточний стан для нащадків:

  • Підкреслення _.any- Лодаш_.some
  • Підкреслення _.all- Лодаш_.every
  • Підкреслення _.compose- Лодаш_.flowRight
  • Підкреслення _.contains- Лодаш_.includes
  • Підкреслення _.each не дозволяє вийти, повертаючисьfalse
  • Підкреслення _.findWhere- Лодаш_.find
  • Підкреслення _.flattenза замовчуванням є глибоким, тоді як Лодаш - неглибоким
  • Підкреслення _.groupByпідтримує ітерацію, для якої передаються параметри (value, index, originalArray), а в Лодаш - ітературу для_.groupBy передається тільки один параметр: (value).
  • Підкреслення _.indexOfз 3-м параметромundefined - Лодаш_.indexOf
  • Підкреслення _.indexOfз 3-м параметромtrue - Лодаш_.sortedIndexOf
  • Підкреслення _.indexBy- Лодаш_.keyBy
  • Підкреслення _.invoke- Лодаш_.invokeMap
  • Підкреслення _.mapObject- Лодаш_.mapValues
  • Підкреслення _.maxпоєднує Лодаш_.max&_.maxBy
  • Підкреслення _.minпоєднує Лодаш _.min&_.minBy
  • Підкреслення _.sampleпоєднує Лодаш _.sample&_.sampleSize
  • Підкреслення _.objectпоєднує Лодаш _.fromPairsі_.zipObject
  • Підкреслення _.omitприсудка - Лодаш_.omitBy
  • Підкреслення _.pairs- Лодаш_.toPairs
  • Підкреслення _.pickприсудка - Лодаш_.pickBy
  • Підкреслення _.pluck- Лодаш_.map
  • Підкреслення _.sortedIndexпоєднує Лодаш _.sortedIndex&_.sortedIndexOf
  • Підкреслення _.uniqпо iterateeє Lodash_.uniqBy
  • Підкреслення _.where- Лодаш_.filter
  • Підкреслення _.isFiniteне узгоджується з Number.isFinite
    (наприклад, _.isFinite('1')повернення trueв підкресленні, алеfalse в Лодаші)
  • _.matchesСтенограма підкреслення не підтримує глибоких порівнянь
    (наприклад _.filter(objects, { 'a': { 'b': 'c' } }))
  • Підкреслення ≥ 1,7 та _.templateсинтаксис Лодаша є
    _.template(string, option)(data)
  • _.memoizeКеші Лодаша - це Mapяк предмети
  • Лодаш не підтримує contextаргумент для багатьох методів на користь_.bind
  • Лодаш підтримує неявне ланцюжок , ледачий ланцюжок та синтез ярликів
  • Lodash розділити його перевантажений _.head, _.last, _.rest, і _.initialз в
    _.take, _.takeRight, _.drop, і _.dropRight
    (тобто _.head(array, 2)в Підкреслення знаходиться _.take(array, 2)в Lodash)

1
Я сам зіткнувся з цими проблемами під час міграції, і я підтримую (WIP) перехресну документацію між однією та іншою. Сподіваюся, що це корисно і іншим людям!
Люксон

60

На додаток до відповіді Джона і читання на лодаші (який я до цього часу вважав "я теж", щоб підкреслити), і бачити тести на ефективність, читати вихідний код і дописи в блогах , кілька пунктів, які викликають лодаш набагато перевершують підкреслення такі:

  1. Йдеться не про швидкість, як про послідовність швидкості (?)

    Якщо ви подивитесь на вихідний код підкреслення, то в перших кількох рядках ви побачите, що підкреслення відновлюється на власних реалізаціях багатьох функцій. Хоча в ідеальному світі це був би кращий підхід, якщо ви подивитеся на деякі посилання на Perf, наведені на цих слайдах , не важко зробити висновок про те, що якість цих "власних реалізацій" багато в чому залежить від браузера, до браузера. Firefox проклятий швидко в деяких функціях, а в деяких Chrome домінує. (Я думаю, були б деякі сценарії, де IE також домінував би). Я вважаю, що краще віддати перевагу коду, чиє виконання є більш послідовним у веб-переглядачах.

    Читайте повідомлення в блозі раніше, і замість того, щоб вірити в це заради себе, судіть самі, запускаючи орієнтири . Я зараз приголомшений, побачивши лодаш, який виконує на 100-150% швидше, ніж підкреслення навіть у простих , рідних функціях, таких як Array.everyу Chrome!

  2. У додаткові послуги в lodash також є дуже корисними.

  3. Що стосується високооціненого коментаря Xananax, який пропонує внесок у код підкреслення: Завжди краще мати ДОБРУ конкуренцію, не тільки це продовжує інновації, але і спонукає вас підтримувати себе (або свою бібліотеку) у хорошій формі.

Ось перелік відмінностей між lodash, і його підкреслення - це заміна заміни для ваших проектів підкреслення.


6
У якому випадку значення "послідовність швидкості"? Скажімо, у мене є метод, який має швидкість 100% у FF та IE, і нативна реалізація матиме швидкість 80% у IE та 120% у FF (або навпаки). Тоді я б сказав, що було б добре використовувати вбудовану реалізацію у FF та власну реалізацію в IE. Я не можу уявити жоден випадок, де я б сказав: Давайте сповільнимо FF лише з тієї причини, щоб мати ту саму швидкість, що і в IE. Розмір коду та ремонтопридатності чи середнє уповільнення у всіх браузерах були б аргументами, але послідовність швидкості?
stofl

2
Я мав на увазі "стабільно
більшу

1
А як щодо різниці в розмірах? Скажімо, ви створюєте власну збірку з lodash, яка має точно такий же функціонал, як і підкреслення? Чи є велика різниця між ними? Я б здогадався, що реалізація додає ваги сайту.
F Lekschas

5
Я схильний відновлюватись до власного втілення браузера просто тому, що в більшості випадків він має прийнятну продуктивність і може покращуватися з оновленнями браузера без побоювання, щоб постійно оновлювати бібліотеку.
orad

3
@KumarHarsh Можливо, я не добре це сформулював. Я мав на увазі, що я схильний використовувати бібліотеку, яка використовує внутрішню функцію, якщо вона доступна, замість того, щоб завжди віддавати перевагу її власній реалізації.
орад

42

Це 2014 рік і на пару років пізно. Я все ж думаю, що моя думка дотримується:

ІМХО ця дискусія досить сильно вибухнула. Цитуючи вищезгадану публікацію в блозі :

Більшість бібліотек утиліти JavaScript, такі як Underscore, Valentine та wu, покладаються на "первісний подвійний підхід". Цей підхід віддає перевагу власним реалізаціям, повертаючись до ванільного JavaScript, лише якщо нативний еквівалент не підтримується. Але jsPerf виявив цікаву тенденцію: найефективніший спосіб ітерації через масив або схожий на масив - це уникати власних реалізацій цілком, замість цього вибираючи прості петлі.

Наче «прості петлі» та «ванільний Javascript» є ріднішими, ніж реалізація методу Array або Object. Боже ...

Звичайно, було б добре мати єдине джерело істини, але цього немає. Навіть якщо вам сказали інакше, боже ванільний, дорогий мій. Мені шкода. Єдине припущення, яке насправді дотримується, - це те, що ми всі пишемо Javascript-код, який спрямований на ефективність роботи у всіх основних браузерах, знаючи, що всі вони мають різні реалізації одних і тих же речей. З сукою впоратися, м’яко кажучи. Але це передумова, сподобалось вам це чи ні.

Можливо, ви працюєте над масштабними проектами, які потребують щебетатих результатів, так що ви дійсно бачите різницю між 850 000 (підкреслення) проти 2 500 000 (лодаш) ітерацій над списком за секунду !

Я для одного не є. Я маю на увазі, що я працював над проектами, де мені доводилося вирішувати проблеми ефективності, але вони ніколи не були вирішені або спричинені ні підкресленням, ні Lo-Dash. І якщо я не захоплюю реальні відмінності у впровадженні та продуктивності (ми зараз говоримо на C ++), давайте дозволяє сказати цикл за ітерабельним (об’єктом чи масивом, розрідженим чи ні!), Я швидше не морочуся жодним претензії, засновані на результатах орієнтованої платформи, яка вже є впевненою .

Потрібно лише одне оновлення, скажімо, Rhino, щоб підпалити його реалізацію методу Array таким чином, що жоден "середньовічний цикл не працює краще і назавжди, а що-небудь" священик може сперечатися з простим фактом, що всі методи раптового масиву у FF набагато швидше, ніж його / її самовпевнений епізод. Людина, ти просто не можеш обдурити своє середовище виконання, обдуривши середовище виконання! Подумайте про це, рекламуючи ...

ваш пояс корисності

... наступного разу.

Отже, щоб це було актуально:

  • Використовуйте підкреслення, якщо вам зручно, не жертвуючи рідним іш.
  • Використовуйте Lo-Dash, якщо вам зручно і вам подобається його розширений каталог функцій (глибока копія тощо), і якщо ви відчайдушно потребуєте в миттєвій продуктивності, а головне, не заперечуйте за рішенням альтернативи, як тільки переїзд рідного API упевнені обходи. Що скоро відбудеться. Період.
  • Є навіть третє рішення. Зробіть! Знайте своє середовище. Знайте про невідповідності. Прочитайте їх код ( Джон-Девід та Джеремі ). Не використовуйте те чи інше, не маючи можливості пояснити, чому дійсно потрібен рівень узгодженості / сумісності та покращує ваш робочий процес або покращує ефективність вашої програми. Цілком ймовірно, що ваші вимоги будуть задоволені простим поліфоном, який ви прекрасно вмієте самостійно писати. Обидві бібліотеки - це просто звичайна ваніль з трохи цукру. Вони обоє просто борються за те, хто подає найсолодший пиріг . Але повірте, врешті-решт обидва готують лише воду. Немає Бога Ванілі, тому не може бути папи Ванілі, правда?

Виберіть будь-який підхід, який найбільше відповідає вашим потребам. Як завжди. Я віддаю перевагу відсіч фактичних реалізацій над виправданими кодами для виконання, але навіть це, здається, є справою смаку в наш час. Дотримуйтесь якісних ресурсів, таких як http://developer.mozilla.com та http://caniuse.com, і у вас все буде добре.


Дякуємо за публікацію Лукаша. Чи можна додатково оптимізувати вбудовані модулі? Я зібрав, що вони мають обмеження, накладені стандартами, які заважають їм оптимізувати порівнянні з бібліотеками, але я детально не знаю деталей, чи це було чи залишається правдою.
Брайан М. Хант

наприклад, "Оптимізуючи для 99% випадків використання, метод fast.js може бути до 5 разів швидшим, ніж їх рідні еквіваленти." - github.com/codemix/fast.js
Брайан М. Хант

1
Привіт Брайан, вибачте, якщо це вводило в оману, я не хотів сказати, що ці бібліотеки не набагато швидші за їх рідні еквіваленти. Якщо ви відчайдушно потребують виконання прямо зараз , ви , ймовірно , краще з інструментарієм , як LoDash або fast.js , як вони забезпечують збільшення швидкості реалізації стандартних методів. Але якщо ви вирішите використовувати бібліотеку, яка не відступає від рідних методів, ви можете просто пропустити будь-які подальші оптимізації продуктивності вбудованих модулів. Браузери з часом розвиватимуться.
Лукас Бюнгер

4
"Виробникам" браузерів важко дотримуватися стандартів своїх веб-переглядачів, які відповідають вимогам, і тим більше вони не працюють. Більшість підвищення продуктивності у власних реалізаціях є результатом більш швидкого обладнання. Пробачення "нативної реалізації" наздожене вже багато років. Роки = вічність в Інтернеті. Якщо рідні реалізації коли-небудь наздоганяють, бібліотеки будуть оновлені для їх використання. Це класна річ з відкритим кодом. Якщо розробник програми не оновлюється до останньої бібліотеки, їх додаток несподівано сповільниться, воно просто не прискориться.
Ендрю Штейц

2
... але якби ви запитали їх про них, Array.fromвони, мабуть, навіть не знали, що це робити. Люди, що видаються з "комунальних служб", настільки сильно переймаються просуванням своїх так геніальних обхідних шляхів, що вони, як правило, забувають, що, роблячи це, вони фактично розріджують процес стандартизації. Відсутність необхідних функцій призводить до тиску на "виробників" браузера. Веселий факт: 2 з 4 основних браузерів засновані на проектах з відкритим кодом ( 1 , 2 ).
Лукас Бюнгер

20

Я згоден з більшістю сказаних тут речей, але я просто хочу навести аргумент на користь underscore.js: розмір бібліотеки.

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

Для порівняння, ці розміри - це ті розміри, які я помітив у джерелі-карт-досліднику після запуску іонного сервісу:

lodash: 523kB
underscore.js: 51.6kb

відредаговано лютого 2020 року :

можна використовувати BundlePhobia, щоб перевірити поточний розмір Lo-Dash та Underscore


1
Дякую Петру, тут варто звернути увагу на це. В інших місцях більше дискусій, зокрема: gist.github.com/alekseykulikov/5f4a6ca69e7b4ebed726 . (Цю відповідь можна було б покращити, пов'язуючи деякі інші дискусії та цитуючи відповідні біти). Різницю в розмірах можна зменшити, вибравши підрозділи лодаш, плюс хитаючи дерева. 🕷
Брайан М. Хант

Thx @ BrianM.Hunt за вашу відповідь, не знав, що можна включити підрозділи лодаш, я буду дивитись. Нещодавно Ionic-native, Ionic взяв такий шлях і для своїх рідних ліб, добре зазначити, що більше більше стурбовані розміром програми
Девід Даль Буско

1
мені цікаво, де ти взяв 523kB? lodash.com каже, що стискається лише 24 КБ. завантажено всього
74 кб

1
моя посада була зроблена у квітні 2017 року, як я сказав у своєму коментарі,source-map-explorer after running ionic serve
Девід Даль Буско

5
У березні 2018 року - lodash.min.js становить 72,5 кБ, а підкреслення-min.js - 16,4 кБ
Поєднайте

10

Не впевнений, чи означає це ОП, але я зіткнувся з цим питанням, оскільки шукав перелік питань, про які я маю пам’ятати, переходячи з підкреслення на лодаш.

Я дуже вдячний, якби хтось опублікував статтю з повним переліком таких відмінностей. Дозвольте почати з того, що я навчився важким шляхом (тобто з речей, які змусили мій код вибухнути на виробництві: /):

  • _.flattenу підкресленні за замовчуванням є глибоким, і вам слід передати true як другий аргумент, щоб зробити його дрібним. У лодаші він за замовчуванням дрібний, і передача істини, оскільки другий аргумент зробить це глибоким! :)
  • _.lastпідкреслення приймає другий аргумент, який говорить про те, скільки елементів ви хочете. У lodashтакому варіанті немає. Ви можете наслідувати це за допомогою.slice
  • _.first (те саме питання)
  • _.templateпідкреслення може використовуватися багатьма способами, одним із яких є надання шаблону рядків та даних та повернення HTMLназад (або, принаймні, так, як це працювало деякий час тому). У lodashвас отримати функцію , яку ви повинні потім годувати з даними.
  • _(something).map(foo)працює в підкресленні, але в лодаші мені довелося це переписати _.map(something,foo). Можливо, це було просто TypeScript-ти

4
У лодаші ланцюг передає лінивий ітератор і вимагає і кінцевої точки, як _(something).map(foo).value().
Брайан М. Хант

Це все може вразити вас, якщо ви використовуєте Backbone Collection, який проксі-сервіси дзвонить до цих бібліотек - наприклад collection.first (5) не дасть вам перших 5 елементів, а скоріше перший :)
qbolec

8

http://benmccormick.org/2014/11/12/underscore-vs-lodash/

Найновіша стаття, яка порівнює дві Бена МакКорміка:

  1. API Lo-Dash - це набір підкреслювачів.

  2. Під капотом [Lo-Dash] був повністю переписаний.

  3. Lo-Dash, безумовно, не повільніше, ніж підкреслення.

  4. Що додав Lo-Dash?

    • Покращення юзабіліті
    • Додаткова функціональність
    • Підвищення продуктивності
    • Короткі синтаксиси для прив’язування
    • Спеціальні побудови використовувати лише те, що вам потрібно
    • Семантична версія та 100% покриття коду

6

Я просто знайшов одну різницю, яка в кінцевому підсумку була для мене важливою. Версія судашів, _.extend()що не підкреслюють, немає копіює властивості чи методи, визначені рівнем класу.

Я створив тест Жасмін в CoffeeScript, який демонструє це:

https://gist.github.com/softcraft-development/1c3964402b099893bd61

На щастя, lodash.underscore.jsзберігається поведінка підкреслення копіювати все, що для моєї ситуації було бажаною поведінкою.


4

лодаш отримав, _.mapValues()який ідентичний підкреслювальному _.mapObject().


0

Здебільшого підкреслення - це підмножина лодаш. Часом, як в даний час, підкреслення матиме прохолодні маленькі функції, lodash не має, як mapObject. Це заощадило мені багато часу на розробці мого проекту.


на той час у нас _.mapValues
crapthings

@crapthings - під час цієї публікації я знав, можливо, MayValues ​​та mapKeys, але вони не такі, як mapObject. Можливо, є випадки застосування одного над іншим, але mapObject - це функція сама по собі.
rashadb

0

Вони досить схожі, Лодаш переймає ...

Вони обидві - це бібліотека утиліт, яка займає світ утиліти у JavaScript ...

Здається, Лодаш зараз регулярно оновлюється, тому більше використовується в останніх проектах ...

Також Лодаш здається, легший на пару КБ ...

В обох є хороший api та doc, але я думаю, Лодаш один кращий ...

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

підкреслення:

підкреслення

lodash: лодаш

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

лодаш

підкреслення

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