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

1542

Почему кто-то предпочитает использовать библиотеку служебных программ lodash.js или underscore.js?

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

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

  • 2
    Возможно, вы захотите взглянуть на некоторые скриншоты о lodash, которые связаны на его странице github. Лично я использую underscore.js, но больше, потому что это то, с чего я начал, и, как вы говорите, это было дольше.
  • 24
    lodash и underscore находятся в процессе слияния
Показать ещё 1 комментарий
Теги:
lodash
underscore.js

14 ответов

1771
Лучший ответ

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

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

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

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

Посмотрите статью Кит Кембридж, скажите "Привет" Lo-Dash, для более глубокого анализа различий между Lo-Dash и Underscore.

Примечания:

  1. Underscore имеет противоречивую поддержку массивов, строк, объектов и arguments объектов. В более новых браузерах методы Underscore игнорируют дыры в массивах, методы "Objects" перебирают объекты arguments, строки обрабатываются как массивы, а методы корректно перебирают функции (игнорируя их свойство "prototype") и объекты (итерируя теневые свойства, такие как "toString") и "valueOf"), тогда как в старых браузерах их не будет. Кроме того, методы Underscore, такие как _.clone сохраняют дыры в массивах, в то время как другие, такие как _.flatten этого не делают.
  • 5
    Спасибо за ответ, Джон-Дэвид, ваши мысли очень ценятся. Считаете ли вы справедливым сказать, что lodash всегда предпочтительнее подчеркивать? (Лучший вопрос: можете ли вы вспомнить кого-то, кто не согласится с этим утверждением?) Большое спасибо.
  • 163
    @Brian - При разработке Lo-Dash я продолжал задавать вопрос: «На что можно было бы указать в Lo-Dash, как на отрицательный результат по сравнению с Underscore?» а затем обратиться к ним. Вот почему я расширил документацию, добавил пользовательские сборки и сделал источник более читабельным.
Показать ещё 20 комментариев
185

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 docs)

  • 1
    Ссылка на блог Кит Кембриджа очень информативна.
  • 0
    Я думаю, что это неправильно (пример срыва). Начиная с последнего обновления 1.8.3, вы можете использовать pluck так же, как lodash. в любом случае для предыдущих версий я не думаю, что подчеркивание представило бы функцию, которая является той же самой картой (ваш пример подчеркивания выглядит как функция карты)
Показать ещё 2 комментария
67

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

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

  • Подчеркивание _.compose - Lodash _.flowRight
  • Подчеркивание _.contains - Lodash _.includes
  • Подчеркивание _.findWhere - Lodash _.find
  • Подчеркивание _.invoke - Lodash _.invokeMap
  • Подчеркивание _.mapObject - Lodash _.mapValues
  • Подчеркивание _.pluck - Lodash _.map
  • Подчеркивание _.where - Lodash _.filter
  • Подчеркивание _.any - Lodash _.some
  • Подчеркивание _.all - Lodash _.every
  • Подчеркивание _.each не позволяет выйти, возвращая false
  • Подчеркивание _.flatten по умолчанию глубокое, а Lodash - неглубоко
  • Подчеркнуть _.isFinite не выравнивается с Number.isFinite
    (например, _.isFinite('1') возвращает true в Underscore, но false в Lodash)
  • Сокращение _.matches Сокращение не поддерживает глубокие сравнения
    (например, _.filter(objects, { 'a': { 'b': 'c' } }))
  • Подчеркивание ≥ 1.7 и Lodash изменили свой синтаксис _.template на _.template(string, option)(data)
  • Lodash _.uniq не принимает функцию iteratee, такую ​​как Underscore. Использовать Lodash _.uniqBy
  • Lodash _.first и ._last не принимают аргумент n, например, Underscore. Используйте slice
  • Lodash _.memoize кэши Map как объекты
  • Lodash поддерживает неявное цепочку, ленивую цепочку и ярлык слитый
  • Лодаш разделил свои перегруженные _.head, _.last, _.rest и _.initial на _.take, _.takeRight, _.drop, & _.dropRight
    (т.е. _.head(array, 2) в подстроке _.take(array, 2) в Лодаше)
  • 1
    Я сам сталкивался с этими проблемами при переносе и поддерживаю перекрестную документацию (WIP), идущую между ними. Надеюсь, что это полезно и для других людей!
60

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

  • Это не о скорости, а о согласованности скорости (?)

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

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

  • дополнительные в lodash также весьма полезны.

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

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

  • 6
    В каком случае «постоянство скорости» является значением? Допустим, у меня есть метод, который имеет скорость 100% в FF и в IE, а нативная реализация будет иметь скорость 80% в IE и 120% в FF (или наоборот). Тогда я бы сказал, что было бы хорошо использовать нативную реализацию в FF и собственную реализацию в IE. Я не могу представить ни одного случая, где я бы сказал: давайте замедлим FF только по той причине, что скорость там такая же, как в IE. Размер кода и удобство сопровождения или среднее замедление во всех браузерах были бы аргументами, но постоянство скорости?
  • 2
    Я имел в виду, «постоянно быстрее скорость»
Показать ещё 10 комментариев
41

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

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

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

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

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

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

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

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

ваш запасной пояс

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

Итак, чтобы это было важно:

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

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

  • 0
    Спасибо за публикацию Лукаса. Можно ли дополнительно оптимизировать встроенные модули? Я понял, что у них есть ограничения, налагаемые стандартами, которые не позволяют им иметь оптимизации, сравнимые с библиотеками, но я не знаю подробностей, а также, было ли это или остается верным.
  • 0
    например: «Оптимизация для 99% -ого варианта использования позволяет ускорить методы fast.js в 5 раз быстрее, чем их собственные эквиваленты». - github.com/codemix/fast.js
Показать ещё 8 комментариев
16

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

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

Для сравнения, эти размеры - те, которые я заметил с помощью source-map-explorer после запуска ионной подачи:

lodash: 523kB
underscore.js: 51.6kb
  • 0
    Спасибо за ваш ответ. Не знал, что можно включить подразделы lodash, чтобы посмотреть. Недавно с ionic-native, Ionic выбрал такой путь и для своих родных библиотек, приятно отметить, что все больше и больше беспокоятся о размере приложения.
  • 1
    Интересно, где вы взяли 523 КБ? lodash.com говорит, что сжато только 24 КБ. загружено только 74kB
Показать ещё 2 комментария
10

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

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

  • _.flatten в подчеркивании глубоко по умолчанию, и вы должны передать true как второй аргумент, чтобы сделать его мелким. В lodash по умолчанию он неглубокий и передается true, поскольку второй аргумент сделает его глубоким!:)
  • _.last в нижнем подчеркивании принимает второй аргумент, который показывает, сколько элементов вы хотите. В lodash такой опции нет. Вы можете эмулировать это с помощью .slice
  • _.first (тот же выпуск)
  • _.template в подчеркивании может использоваться многими способами, один из которых предоставляет строку шаблона и данные и возвращает HTML назад (или, по крайней мере, то, как он работал некоторое время назад). В lodash вы получаете функцию, которую вы должны затем подавать с данными.
  • _(something).map(foo) работает в подчеркивании, но в lodash мне пришлось переписать его на _.map(something,foo). Возможно, это был только TypeScript -issue
  • 3
    В lodash сцепление проходит ленивый итератор, и требует и конечную точку, такую как _(something).map(foo).value() .
  • 0
    Это все может вас поразить, если вы используете Backbone Collection, которая использует прокси-вызовы для этих библиотек - например, collection.first (5) не даст вам первые 5 элементов, а скорее первый :)
9

Существует движение к объединению двух библиотек. Отличная идея, я думаю!

https://github.com/jashkenas/underscore/issues/2182

8

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

Последняя статья, сравнивающая их Бена Маккормика:

  • Lo-Dash API - это надмножество Underscore.

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

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

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

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

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

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

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

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

3

lodash имеет _.mapValues(), который идентичен недоэкспорту _.mapObject().

0

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

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

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

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

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

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

нижнее подчеркивание:

Изображение 2138

Лодаш: Изображение 2139

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

lodash

нижнее подчеркивание

0

Они очень похожи, с Лодашем в данный момент вступает во владение...

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

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

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

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

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

нижнее подчеркивание:

Изображение 2138

Лодаш: Изображение 2139

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

lodash

нижнее подчеркивание

0

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню