Различия между lodash и подчеркиванием [закрыто]

1602

Почему кто-то предпочитает библиотеку утилит lodash.js или underscore.js другим?

Lodash, кажется, является заменой нижнего подчеркивания, последний был дольше.

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

Брайан М. Хант
источник
2
Возможно, вы захотите взглянуть на некоторые скриншоты о lodash, которые связаны с его страницей на github. Лично я использовал underscore.js, но больше, потому что это то, с чего я начал, и, как вы говорите, это было дольше.
Джек,
26
lodashи underscoreнаходятся под слиянием нити в настоящее время
zangw
К вашему сведению: блокнот Underscore & Lodash
user2875289

Ответы:

2024

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

Поскольку Lo-тир обновляется чаще , чем подчёркивание lodash underscoreсборка обеспечиваются , чтобы обеспечить совместимость с последней версией стабильного подчёркивания.

В какой-то момент мне даже дали толчок доступ к Underscore, отчасти потому, что Lo-Dash отвечает за поднятие более 30 проблем; исправления ошибок при посадке, новые функции и улучшения в Underscore v1.4.x +.

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

Посмотрите на статью Кита Кембриджа « Скажи« Привет »Ло-Дашу» , чтобы узнать о различиях между Ло-Даш и Ундерскоре.

Примечания:

  1. Underscore имеет несовместимую поддержку для массивов, строк, объектов и argumentsобъектов. В более новых браузерах методы Underscore игнорируют дыры в массивах , методы «Objects» перебирают argumentsобъекты, строки обрабатываются как массивы, а методы корректно перебирают функции (игнорируя их свойство «prototype») и объекты (итерируя свойства с затенением, такие как «toString» и "valueOf"), тогда как в старых браузерах их не будет. Кроме того, методы Underscore, такие как _.cloneсохранить дыры в массивах, а другие, как _.flattenнет.
Джон-Дэвид Далтон
источник
174
@Brian - При разработке Lo-Dash я продолжал задавать вопрос: «На что можно было бы указать в Lo-Dash, как на негатив по сравнению с Underscore?» а затем обратиться к ним. Вот почему я расширил документацию, добавил пользовательские сборки и сделал источник более читабельным.
Джон-Дэвид Далтон
10
Я очень соблазняюсь опубликовать некоторые тесты, но это может стать утомительным. Достаточно сказать, что каждый тест, который я выполнял, доказывал, что Lo-Dash быстрее ( НАМНОГО быстрее во многих случаях), чем подчеркивание.
Уил Мур III
186
Я люблю lo-dash и использую его, поэтому, пожалуйста, не думайте, что я ругаюсь, но почему бы не сделать акцент на подчеркивании вместо создания новой библиотеки?
Ксананакс,
133
@Xananax - проверьте ветку комментариев: github.com/jashkenas/underscore/commit/… - это может ответить на этот вопрос.
Роб Грант
41
Были ли какие-либо попытки вернуть lodash обратно в подчеркивание?
уличный
186

Lo-Dash вдохновлен подчеркиванием, но в настоящее время это превосходное решение. Вы можете создавать свои собственные сборки , иметь более высокую производительность , поддерживать AMD и иметь отличные дополнительные функции . Проверьте тесты Lo-Dash и 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 )

neiker
источник
1
Ссылка на блог Кит Кембриджа очень информативна.
Брайан М. Хант
Я думаю, что это неправильно (пример срыва). Начиная с последнего обновления 1.8.3, вы можете использовать pluck так же, как lodash. в любом случае для предыдущих версий я не думаю, что подчеркивание представило бы функцию, которая является той же самой картой (ваш пример подчеркивания выглядит как функция карты)
alexserver
7
filterособенность в подчеркивании с 2012 года github.com/jashkenas/underscore/issues/648 (его зовут where)
Мухаммед Хьюди
Я получаю сообщение об ошибке 500 по ссылке на тест Lo-Dash vs Underscore
Hylle
86

Если, как и я, вы ожидаете получить список различий между подчеркиванием и lodash, есть руководство по переходу с подчеркивания на lodash .

Вот текущее состояние для потомков:

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

В дополнение к ответу Джона, чтению lodash (которое я до сих пор считал «я тоже», чтобы подчеркнуть), а также ознакомлению с тестами производительности, чтением исходного кода и сообщениями в блоге , некоторые моменты, которые делают lodash намного лучше, чем подчеркнуть это:

  1. Дело не в скорости, а в постоянстве скорости (?)

    Если вы посмотрите на исходный код подчеркивания, вы увидите, что в первых нескольких строках подчеркивается откат к собственным реализациям многих функций. Хотя в идеальном мире это был бы лучший подход, если вы посмотрите на некоторые ссылки на Perf, приведенные на этих слайдах , нетрудно сделать вывод, что качество этих «нативных реализаций» сильно варьируется в зависимости от браузера. в браузере. Firefox чертовски быстр в некоторых функциях, а в некоторых Chrome доминирует. (Я предполагаю, что были бы некоторые сценарии, где IE также доминировал бы). Я считаю, что лучше отдать предпочтение коду, чья производительность более стабильна во всех браузерах.

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

  2. В дополнительных услугах в lodash также являются весьма полезными.

  3. Что касается высоко оцененного комментария Xananax, предлагающего вклад в код подчеркивания: всегда лучше иметь ХОРОШУЮ конкуренцию, она не только поддерживает инновации, но и заставляет вас поддерживать себя (или свою библиотеку) в хорошей форме.

Вот список различий между lodash, и его подчеркивание - это замена для ваших проектов подчеркивания.

kumarharsh
источник
6
В каком случае «постоянство скорости» является значением? Допустим, у меня есть метод, который имеет скорость 100% в FF и в IE, а нативная реализация будет иметь скорость 80% в IE и 120% в FF (или наоборот). Тогда я бы сказал, что было бы хорошо использовать встроенную реализацию в FF и собственную реализацию в IE. Я не могу представить ни одного случая, где я бы сказал: давайте замедлим FF только по той причине, что скорость там такая же, как в IE. Размер кода и удобство сопровождения или среднее замедление во всех браузерах были бы аргументами, но постоянство скорости?
stofl
2
Я имел в виду, «неизменно быстрее скорость»
kumarharsh
1
Как насчет разницы в размере? Допустим, вы создаете пользовательскую сборку с lodash, которая имеет те же функции, что и подчеркивание? Есть ли большая разница между ними? Я предполагаю, что повторная реализация добавляет вес сайту.
Ф Лекшас
5
Я склонен откатываться к собственной реализации браузера просто потому, что в большинстве случаев он имеет приемлемую производительность и может улучшаться с обновлениями браузера, не беспокоясь о том, чтобы поддерживать библиотеку в актуальном состоянии.
Орад
3
@KumarHarsh Может быть, я не очень хорошо сформулировал это. Я имел в виду, что я склонен использовать библиотеку, которая использует внутренние функции, если они доступны, вместо того, чтобы всегда отдавать предпочтение своей собственной реализации.
Орад
42

Это 2014 год и на пару лет поздно. Тем не менее, я думаю, что моя точка зрения верна:

ИМХО, эта дискуссия разлетелась совсем немного. Цитирую вышеупомянутую запись в блоге :

Большинство утилитарных библиотек JavaScript, таких как Underscore, Valentine и wu, полагаются на «двойной родной подход». Этот подход предпочитает нативные реализации, возвращаясь к обычному JavaScript, только если нативный эквивалент не поддерживается. Но jsPerf обнаружил интересную тенденцию: наиболее эффективный способ перебора массива или массива, подобного массиву, - полностью избежать нативных реализаций, выбрав вместо этого простые циклы.

Как будто «простые циклы» и «ванильный Javascript» являются более нативными, чем реализации метода Array или Object. Боже ...

Конечно, было бы неплохо иметь единый источник правды, но это не так. Даже если тебе сказали иначе, ванильного бога нет, моя дорогая. Мне жаль. Единственное предположение, которое действительно справедливо, заключается в том, что мы все пишем код Javascript, который направлен на то, чтобы хорошо работать во всех основных браузерах, зная, что все они имеют разные реализации одних и тех же вещей. С этим сука, мягко говоря, справиться. Но это предпосылка, нравится вам это или нет.

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

Я, например, нет. Я имею в виду, я работал над проектами, где мне приходилось решать проблемы с производительностью, но они никогда не были решены или вызваны ни Underscore, ни Lo-Dash. И пока я не пойму реальные различия в реализации и производительности (мы сейчас говорим о C ++), скажем, цикла над итеративным (объект или массив, разреженным или нет!), Я скорее не буду беспокоиться о каких-либо претензии, основанные на результатах эталонной платформы, которая уже высказана .

Нужно всего лишь одно обновление, скажем, Rhino, чтобы зажечь свои реализации метода Array таким образом, чтобы ни один «средневековый цикл не работал лучше и навсегда, а священник с чем угодно» не мог спорить о том, что все Методы внезапного массива в FF намного быстрее, чем его / ее самоуверенный псих. Чувак, ты просто не можешь обмануть свою среду выполнения, обманув свою среду выполнения! Подумайте об этом при продвижении ...

ваш сервисный пояс

... в следующий раз.

Итак, чтобы сохранить это актуальным:

  • Используйте Underscore, если вам это удобно, не жертвуя нативным ишем.
  • Используйте Lo-Dash, если вам удобно, и вам нравится его расширенный каталог функций (глубокое копирование и т. Д.), И если вы остро нуждаетесь в мгновенной производительности и, самое главное, не возражаете против выбора альтернативы, как только устаревший API упрямые обходные пути. Что скоро произойдет. Период.
  • Есть даже третье решение. DIY! Знай свое окружение. Знайте о несоответствиях. Прочитайте их ( Джон-Дэвид и Джереми ) код. Не используйте то или это, не имея возможности объяснить, почему действительно необходим уровень согласованности / совместимости, который улучшает рабочий процесс или повышает производительность вашего приложения. Весьма вероятно, что ваши требования будут удовлетворены простым полифилом, который вы сможете написать самостоятельно. Обе библиотеки просто ванильные с небольшим количеством сахара. Они оба борются за то, кто подает сладкий пирог . Но, поверьте мне, в конце концов, оба готовят только с водой. Нет ванильного бога, поэтому не может быть и ванильного папы, верно?

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

Лукас Бюнгер
источник
Спасибо за публикацию Лукаса. Можно ли дополнительно оптимизировать встроенные модули? Я понял, что у них есть ограничения, налагаемые стандартами, которые не позволяют им проводить оптимизации, сравнимые с библиотеками, но я не знаю подробности, или это было или остается верным.
Брайан М. Хант
например, «Оптимизируя для 99% сценария использования, методы fast.js могут быть в 5 раз быстрее, чем их собственные эквиваленты». - github.com/codemix/fast.js
Брайан М. Хант,
1
Привет, Брайан, извини, если это вводило в заблуждение, я не хотел сказать, что эти библиотеки не намного быстрее, чем их собственные эквиваленты. Если вы отчаянно нуждаются в выполнении прямо сейчас , вы , вероятно , лучше с инструментарием , как LoDash или fast.js , как они обеспечивают увеличение скорости реализации стандартных методов. Но если вы решите использовать библиотеку, которая не использует нативные методы, вы можете просто пропустить любые будущие оптимизации производительности встроенных модулей. Браузеры будут развиваться в конце концов.
Лукас Бюнгер
4
«Производители» браузеров с трудом соблюдают стандарты своих браузеров, не говоря уже о производительности. Большая часть прироста производительности в нативных реализациях является результатом более быстрого оборудования. «Родные реализации наверстают упущенное», оправдание существует уже много лет. Годы = вечность в интернете. Если нативные реализации когда-нибудь догонят, библиотеки будут обновлены, чтобы использовать их. Это крутая вещь с открытым исходным кодом. Если разработчик приложения не обновляется до последней библиотеки, его приложение не будет внезапно замедляться, оно просто не будет ускоряться.
Эндрю Штейтц
2
... но если бы вы спросили их об этом, Array.fromони, вероятно, даже не знали бы, что он должен делать. Люди из «сервисного пояса» JS, похоже, настолько сильно озабочены продвижением своих очень благородных обходных путей, что склонны забывать, что этим они фактически ослабляют процесс стандартизации. Отсутствие необходимости в функциях не приводит к давлению на «производителей» браузеров. Интересный факт: 2 из 4 основных браузеров основаны на проектах с открытым исходным кодом ( 1 , 2 ).
Лукас Бюнгер
20

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

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

Для сравнения, эти размеры те, которые я заметил с source-map-explorer после запуска ionic serve:

lodash: 523kB
underscore.js: 51.6kb

отредактировано февраль 2020 :

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

Дэвид Даль Буско
источник
1
Спасибо Питер, это стоит отметить здесь. В других местах обсуждается больше вопросов, в том числе: gist.github.com/alekseykulikov/5f4a6ca69e7b4ebed726 . (Этот ответ можно улучшить, связав некоторые другие обсуждения и процитировав соответствующие биты). Разницу в размере можно уменьшить, выбрав подразделы lodash, плюс lodash с потрясающими деревьями. B
Брайан М. Хант
Спасибо за ваш ответ, не знал, что можно включить подразделы lodash, чтобы посмотреть. Недавно с ionic-native Ionic пошла по такому пути и для своих родных библиотек, приятно отметить, что все больше и больше беспокоятся о размере приложения
Дэвид Дал Буско,
1
Интересно, где вы взяли 523 КБ? lodash.com говорит, что сжато только 24 КБ. загруженное только 74KB
Martian2049
1
мой пост был сделан в апреле 2017 года. как я уже сказал в своем комментарии,source-map-explorer after running ionic serve
Дэвид Даль Буско
5
В марте 2018 года - lodash.min.js составляет 72,5 кБ, а подчеркивание min.js - 16,4 кБ
объединение
10

Не уверен, что именно это и имел в виду OP, но я столкнулся с этим вопросом, потому что искал список проблем, о которых нужно помнить при переходе с подчеркивания на lodash.

Я был бы очень признателен, если бы кто-то опубликовал статью с полным списком таких различий. Позвольте мне начать с вещей, которые я выучил трудным путем (то есть вещей, которые заставили мой код взорваться на производстве: /):

  • _.flattenв подчеркивании по умолчанию глубокий, и вы должны передать true в качестве второго аргумента, чтобы сделать его поверхностным. В lodash по умолчанию он неглубокий, и передача true в качестве второго аргумента сделает его глубоким! :)
  • _.lastв подчеркивании принимает второй аргумент, который говорит, сколько элементов вы хотите. У lodashтакой возможности нет. Вы можете подражать этому с.slice
  • _.first (та же проблема)
  • _.templateв подчеркивании можно использовать по-разному, одним из которых является предоставление строки шаблона и данных и получение HTMLобратно (или, по крайней мере, так это работало некоторое время назад). В lodashвы получите функцию, которую вы должны затем передать с данными.
  • _(something).map(foo)работает в подчеркивании, но в lodash мне пришлось его переписать _.map(something,foo). Возможно, это был просто TypeScriptвопрос
qbolec
источник
4
В lodash, цепочка проходит ленивый итератор, и требует и конечную точку, как _(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 - это расширенный набор Underscore.

  2. Под капотом [Lo-Dash] была полностью переписана.

  3. Lo-Dash определенно не медленнее, чем Underscore.

  4. Что добавил Lo-Dash?

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

Я только нашел одно различие, которое оказалось важным для меня. Без подчёркивания-совместимая версия lodash - х _.extend()вовсе не копировать уровня класса определенных свойств или методов.

Я создал тест Жасмин в CoffeeScript, который демонстрирует это:

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

К счастью, lodash.underscore.jsсохраняет поведение Underscore копировать все, что для моей ситуации было желаемым поведением.

Крейг Уокер
источник
4

У Лодаша есть _.mapValues()что-то такое же, как у младших _.mapObject().

artknight
источник
0

По большей части подчеркивание является подмножеством lodash. Время от времени, как в настоящее время подчеркивание будет иметь классные маленькие функции, lodash не имеет, как mapObject. Этот сэкономил мне много времени при разработке моего проекта.

rashadb
источник
в то время у нас есть _.mapValues
crapthings
@crapthings - на момент написания этой статьи я знал о mayValues ​​и mapKeys, но они не совпадают с mapObject. Может быть, есть случаи, чтобы применить один поверх другого, но mapObject - это отдельная функция.
Рашадб
0

Они очень похожи, с Лодашем ...

Они оба являются утилитарной библиотекой, которая берет мир полезности в JavaScript ...

Кажется, что Lodash теперь обновляется более регулярно, поэтому его чаще используют в последних проектах ...

Кроме того, Lodash кажется легче на пару килобайт ...

Оба имеют хороший API и док, но я думаю, что Lodash один лучше ...

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

подчеркивать:

подчеркивать

lodash: lodash

Поскольку вещи могут обновляться время от времени, просто проверьте их веб-сайт также ...

lodash

подчеркивать

Алиреза
источник