Lo-Dash

Автор оригинала: John-David Dalton
  • Перевод
Прим. переводчика: underscore.js — одна из самых известных и любимых javascript-библиотек. Но мало кто знает, что есть её более удачный клон. В одном из своих проектов мы без каких-либо проблем перешли на него и теперь решили познакомить с ним других читателей Хабрахабра.

Lo-Dash — это полноценная замена* для Underscore.js. Lo-dash имеет более высокую производительность, избавлен от некоторых багов underscore и даёт некоторые новые возможности.



Новые возможности:


  • Поддержка AMD-загрузчиков (RequireJS, curl.js, etc.)
  • _.clone поддерживает “глубокое” клонирование
  • _.forEach поддерживает текучий интерфейс и остановку итерирования
  • _.forIn для итерирования по собственным и унаследованным свойствам объектов
  • _.forOwn для итерирования только по собственным свойствам объекта
  • _.isPlainObject проверяет, было ли значение создано с помощью конструктора Object
  • _.lateBind для позднего связывания
  • _.merge“глубокий” аналог _.extend
  • _.partial для карринга без связывания this
  • _.pick и _.omit принимают аргументы callback и thisArg
  • _.template использует sourceURLs для более простой отладки
  • _.contains, _.size, _.toArray, и т.д.… принимают и строки тоже


Индивидуальные сборки


Поддержка индивидуальных сборок позволяет легко создавать облегчённые версии Lo-Dash, содержащие только необходимые вам методы. Также Lo-Dash поддерживает за вас зависимости методов и псевдонимы.

  • Сборка, содержащая всё необходимое для работы Backbone, может быть создана с модификатором backbone.
    lodash backbone
    
  • Content Security Policy сборка.
    lodash csp
    
  • Сборка для старых браузеров без поддержки ES5.
    lodash legacy
    
  • Сборки для мобильных платформ, без баг-фиксов для IE < 9 и компиляции методов.
    lodash mobile
    
  • Strict-сборки, с использованием strict mode для _.bindAll, _.defaults, and _.extend.
    lodash strict
    
  • Underscore-сборка, для тех, кто уже используется Underscore в своих проектах.
    lodash underscore
    

и т.д.

Куда пойти, куда податься?


Alawar Entertainment
Компания
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 31

    +13
    Lo-dash имеет более высокую производительность, т.к. создан авторами сайта jsPerf.com

    Аргумент…
      +2
      Эти ребята знают, что делают. Можете сами проверить: lodash.com/benchmarks
        +1
        Ну хрен знает, была у меня функция для поиска пересечений на два аргумента, расширил её до [2..n] аргументов за 10 минут. Правда она стала не красивой после этого расширения, но вот результат.
          0
          Если я правильно понял, то Вы помещаете значения в ключи хэша, тем самым используя сильные стороны этой структуры.
          Однако, это не будет работать со значениями, отличными от скаляров,. Но да, для чисел Ваш алгоритм работает хорошо.
            0
            Даже не подумал что такое может случиться. Код использовался в вычислениях до этого. Но пересечь функции, пожалуй, иногда действительно может быть полезно.
        0
        Тоже сразу в глаза бросилось :)
          0
          Но ладно, Ваша взяла :)
          0
          Странно, что underscore в некоторых бенчмарках быстрее.
          Но если полноценная замена, говорите, то можно попробовать. Во всяком случае, плюшки радуют.
            0
            Ну часто underscore быстрее на пару процентов всего, это в пределах погрешности и обычно их алгоритмы в этих случаях совпадают.
            Когда underscore быстрее значительно (а таких случаев немного), я это объясняю тем, что в среднем по всем браузерам эта реализация скорее всего лучше, но конкртно в этом — тормозит. По факту же, у себя в проекте такие медленные функции использовать не доводилось, так что для меня выбор в пользу Lo-Dash получился бескомпромиссным.
              +1
              Ну странный браузер (хром) и маловероятность функций (clone и contains) не отменяют факт. Мне просто интересно, почему они эти функции не сделали быстрее, ведь элементарно же было сделать хотя-бы не_медленнее. По факту эти функции действительно редкость.
                +2
                Lo-Dash нормально копирует цепочку прототипов. Попробуйте в консоле хрома
                _(Object.create(Object.create({q:1,w:2,e:3}))).clone()

                и рассмотрите цепочку __proto__.
                contains тоже переписана для поддержки не только массивов, правда не понимаю, зачем так усложнена в коде.
                  0
                  Это приятно, да. Clone в underscore это обычный exntend пустого объекта.
                    0
                    У меня lodash.clone() и не клонирует этот объект :)
                    > var lodash = require('lodash');
                    undefined
                    > var a = Object.create(Object.create({q:1,w:2,e:3}));
                    undefined
                    > var b = lodash.clone(a);
                    undefined
                    > a === b
                    true
                    

                    Если что, речь про node.js 0.8.15.
                      0
                      О как… И правда клонирование поломали, раньше работало:) Хотя пофик, нигде не использую.
                      Если так тема копирования волнует — более простые велосипеды использую — тык.
                      Работает и в ноде, и в браузерах, в т.ч. старых. Стандартные объекты, глубокое, сохранение цепочки прототипов, в отличии от большинства велосипедов — клонирование дескрипторов.
                      За скоростью не гонюсь, есть более быстрый варианты.
                        0
                        Отлично. Я тут затеял глобальное исследование на эту тему.
                        Прогоню и Ваш клонер через тесты и бенчмарки .-)
                        Про дескрипторы не поскажете поподробнее, что требуется? Или, может, код теста подкините?
                          0
                          С дескрипторами все просто — getOwnPropertyDescriptor для получения, defineProperty для установки. Дабы лишний раз геттеры не вызывать — для получения значения — value объекта getOwnPropertyDescriptor. Перед установкой delete затереть старые дескрипторы, перед слиянием value проверить наличие геттеров и сеттеров, хотя это скорее для слияния объектов. Скорость клонирования, само собой, падает в несколько(5-7 у меня) раз, так что фича не для включения по дефолту.
                          0
                          судя по моим тестам ( github.com/AlexeyKupershtokh/node-v8-clone/blob/master/test/shared.js ), у Вас в shallow-версии падают эти:
                          1) should clone number objects
                          2) should clone strings objects
                          3) should preserve Date instances custom properties
                          4) should preserve RegExp instances custom properties
                          5) should clone Functions
                          6) should preserve Functions custom properties
                          7) should clone inherited instances
                          В deep-версии добавляются еще такие:
                          15) should deeply clone Function custom properties
                          16) should deeply clone Date instances custom properties
                          17) should deeply clone RegExp instances custom properties
                          Их них важные наверное только 1, 2 и 7.
                            0
                            Гмм, у меня этот функционал покрыт тестами, унылыми, но полностью, все проходит, тесты прилагаются. Да и на продакшне без проблем. Полностью тест не прогнал, но в консоли 1,2,7 проходят без проблем. Похоже не так велосипед прикрутили:) Клонирование функций и custom properties стандартных конструкторов не предусмотрено, легко сделать — но замедлит код.
                              0
                              Прошу прощения. Неправильно вызывал ваш код, из-за чего возникла коллизия с другим модулем. Исправил, перезапустил.
                              Результаты теста.
                                zloirock Object.clone(value)
                                  should clone primitives
                                    ✔ should clone null 
                                    ✔ should clone undefined 
                                    ✔ should clone boolean 
                                    ✔ should clone numbers 
                                    ✔ should clone strings 
                                  should clone builtin objects
                                    ✔ should clone number objects 
                                    1) should preserve number object custom properties
                                    ✔ should clone strings objects 
                                    2) should preserve string object custom properties
                                    ✔ should clone {} objects 
                                    ✔ should clone Object.create(null) objects 
                                    ✔ should clone inherited objects 
                                    ✔ should clone arrays 
                                    3) should preserve array custom properties
                                    ✔ should clone Date instances 
                                    4) should preserve Date instances custom properties
                                    ✔ should clone RegExp instances 
                                    5) should preserve RegExp instances custom properties
                                    ✔ should clone Arguments 
                                    6) should preserve Arguments custom properties
                                    7) should clone Functions
                                    8) should preserve Functions custom properties
                                  should clone custom objects
                                    ✔ should clone instances 
                                    ✔ should clone inherited instances 
                              
                                zloirock Object.clone(value, true)
                                  should clone primitives
                                    ✔ should clone null 
                                    ✔ should clone undefined 
                                    ✔ should clone boolean 
                                    ✔ should clone numbers 
                                    ✔ should clone strings 
                                  should clone builtin objects
                                    ✔ should clone number objects 
                                    9) should preserve number object custom properties
                                    ✔ should clone strings objects 
                                    10) should preserve string object custom properties
                                    ✔ should clone {} objects 
                                    ✔ should clone Object.create(null) objects 
                                    ✔ should clone inherited objects 
                                    ✔ should clone arrays 
                                    11) should preserve array custom properties
                                    ✔ should clone Date instances 
                                    12) should preserve Date instances custom properties
                                    ✔ should clone RegExp instances 
                                    13) should preserve RegExp instances custom properties
                                    ✔ should clone Arguments 
                                    14) should preserve Arguments custom properties
                                    15) should clone Functions
                                    16) should preserve Functions custom properties
                                  should clone custom objects
                                    ✔ should clone instances 
                                    ✔ should clone inherited instances 
                                  should deeply clone objects
                                    17) should deeply clone BooleanObject instances custom properties
                                    18) should deeply clone NumberObject instances custom properties
                                    19) should deeply clone StringObject instances custom properties
                                    20) should deeply clone Function custom properties
                                    21) should deeply clone Date instances custom properties
                                    22) should deeply clone RegExp instances custom properties
                                    ✔ should deeply clone nested objects 
                                    ✔ should deeply clone nested arrays 
                                    23) should deeply clone arrays with custom properties
                                  should deeply clone circular objects
                                    24) should clone nested objects with internal refs
                                    25) should deeply clone circular arrays
                                    26) should deeply clone circular objects
                                    27) should deeply clone circular objects (lodash version)
                              

                                0
                                К слову, node-v8-clone проходит все эти тесты. С одной оговоркой: там есть 2 pending теста касательно буферов и контекста замыканий. С ними пока не решил, что делать, и нужно ли/можно ли их клонировать :)
                                  0
                                  Вкусно, конечно, но только для ноды. Нужен был бы только сервер — и я бы модули на сях писал:) Ну а по тестам — про custom properties и клонирование функций — как писал — легко, но, средствами js, слишком дорого. Могу изменить за пару минут — будет проходить почти все. Но толку?)
                                  А насчет circular — подумаю, может добавлю:)
                        +1
                        или, чтоп совсем уж понятно было, сравните в Lo-Dash и Underscore
                        function fn(){};
                        _.clone(new fn) instanceof fn;
                        
                  +1
                  с backbone.js совместим? в смысле можно использовать как замену андерскор для бэкбон проектов?
                    0
                    На ToDoMVC пример с Backbone использует как раз Lo-Dash.
                    Да и был бы не совместим — много проблем бы вызвало? Как-то со скуки всего около часа понадобилось, что-бы Backbone с Underscore на Sugar перепилить.
                      0
                      просто интересно стало.
                      да и иногда нужно сделать что то клевое быстро, не задумываясь.
                      backbone + _ + zepto спасли пару раз
                      +1
                      У Lo-Dash есть 2 сборки специально для Вас:
                      Сборка с повышенной совместимостью lodash underscore, которая может пригодиться, если не получится завести со стандартной.
                      Также есть минималистичная версия именно для Backbone lodash backbone.
                      +1
                      Если в underscore ничего не поменялось, то _.difference в lodash на больших объёмах (сотни тысяч) работает в овер 650 раз быстрее :)

                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                    Самое читаемое