Lodash - функции будущего в JS уже сегодня

Konstantin
Konstantin Ostrovsky
2018-12-06 08:11:23
15

Каждый разработчик ценит свое время и всегда ищет способы избежать дублирования кода и написания одинаковых реализаций под различные проекты. Lodash - библиотека с огромным количеством функций для работы с различными структурами данных. Опытный программист всегда найдет способ не писать велосипеды с костылями, а использовать готовые, проверенные решения. Тем более если эти решения хорошо структурированы и отлично задокументированы

Lodash - это библиотека JavaScript, которая помогает программистам писать более компактный и простой в обслуживании JavaScript код.

Его можно разбить на несколько основных направлений:

  • Utilities - для упрощения общих задач программирования, таких как определение типа, а также упрощение математических операций.;
  • Function - упрощение связывания, декорирование, сдерживание, дросселирование, debouncing, currying и изменение указателя;
  • String - функции преобразования для выполнения основных операций с строками, такие как обрезка, преобразование в верхний регистр, случай верблюда и т.д.;
  • Array - создание, разбиение, объединение, изменение и сжатие;
  • Collection - итерация, сортировка, фильтрация, расщепление и строительство;
  • Object - доступ, расширение, слияние, дефолты и преобразование;
  • Seq  - caching, упаковка, фильтрация и тестирование.

 

Библиотека доступна для установки с CDN без использования сборщиков, доступна на npm, есть поддержка TypeScript. Начать пользоваться Lodash очень просто, поэтому мы не будем уделять внимание установке. Если у Вас возникнут сложности - можете обратиться к документации, здесь подробно рассмотрены все варианты подключения библиотеки.

С появлением ES6 репутация Lodash слегка пошатнулась для некоторых разработчиков. Причиной этому стало появление большого количество функций для работы с структурами и добавление новых типов данных. В ES6 появилось большое количество функций для работы с массивами:

  • forEach - используется для перебора массива;
  • filter - используется для фильтрации массива через callback функцию;
  • map -  используется для трансформации массива;
  • every/some - методы используются для проверки массива;
  • reduce/reduceRight - используется для последовательной обработки каждого элемента массива с сохранением промежуточного результата.

Более подробную информацию по этим функциям Вы можете найти здесь.

Так же появились такие нововведения как:

Но несмотря на это польза библиотеки все равно не вызывает ни капли сомнения, JavaScript еще не скоро "впитает" или повторит все возможности Lodash.

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

Предположим что мы делаем интернет-магазин и что бы снизить нагрузку на сервер мы решили переложить сложную логику сортировки и фильтрации на JavaScript. Логика будет следующая:

1) Пользователь открывает страницу - подгружаются все товары магазина и кладутся в переменную;

2) При взаимодействии с фильтрами и сортировками - JavaScript выполняет манипуляции с данными и выводит их пользователю;

В терминологии lodash коллекция - это набор объектов(сущностей), который заключен в массив. В данном случае наши товары являются сущностями, а массив с товарами - коллекцией. Таким образом мы можем применять все методы для коллекций из существующих в Lodash. Наши товары будут представлены в виде объектов и собраны в коллекцию вида:


var products = [
    {
        id: 0,
        name: "Товар 1",
        price: 1200,
        color: "Красный",
        размер: "XL"
    },
    ....
]

Lodash хранится в переменной _. С технической стороны: переменная _   - это объект Lodash, который содержит в себе множество методов (свойств).  Из этого следует что к переменной Lodash можно обращаться как к обычному объекту, используя "_.<method name>", таким образом для вызова функции "filter" нам потребуется написать следующее "_.filter(...)". Это важно для понимания и правильного восприятия структуры библиотек, во избежание эффекта "абракадабры" для разработчика (я написал вот так, а оно там как-то само все сделало). 

Для реализации задумки необходимо вывести два фильтра и одну сортировку:

  1. по цвету;
  2. по размеру;
  3. сортировка по цене.

Дабы сильно не заморачиваться, я сделал простые <select> и повесил на них обработчики события "change". При смене значения, мы будем производить фильтрацию и выводить новый список товаров. 

Так как нам нужно что-то выводить, давайте напишем функцию "render"(название не принципиально). Работает эта функция до слез в глазах примитивно и не оптимизировано, но сейчас не об этом. Принцип ее работы следующий: принимаем агрументом массив с товарами, очищаем "<div>" в который выводятся товары и в цикле выводим все товары из массива используя шаблонные строки ES6:

// Функция вывода товаров
function render(data = []) {
  $("#listing").empty()  // Очищаем контейнер
  for(let product of data) {
    $("#listing").append($(`
      <div class="product">
        <p><b>${product.name} (${product.id})</b></p>
        <p>${product.color}, ${product.size}</p>
        <p>Цена: ${product.price}</p>
      </div>
    `)) // Добавляем товары по шаблону
  }
  
  $("#total").text(`Найдено ${data.length} товаров`) // Выводим общее количество товаров
}

Вручную формировать список товаров - не самое интересное занятие, он будет генерироваться случайным образом. Для этого можно использовать функции random и uniqueId.

Кульминация события - функция filter. Функция работает с объектом  filterData, и формирует новый список отсортированных и фильтрованных товаров, но основе базового списка. Для фильтрации товаров по свойствам цвета и размера можно использовать функции Lodash - filter и orderBy.

Вот что в итоге получилось:

See the Pen Lodash demo by Konstantin (@ssstelllo) on CodePen.

Результат на лицо - мы сократили достаточно сложные операции с данными до 1 строки кода. Библиотека безусловно заслуживает внимания и полагаясь на выбор миллионов разработчиков, можно смело использовать ее в своих проектах. Нет сомнения что со временем библиотека уйдет в бытие, когда JavaScript "из коробки" будет поддерживать все эти функции, но это не самая близкая перспектива, так что радуемся и пользуемся на здоровье!

 

Ниже представлен список наиболее популярных функций с описанием, который я позаимствовал у zag2art, за что ему большое спасибо.

Источник

 

Массивы
compact
Убираем из массива все пустые элементы (0, "", nullundefined)
difference
Создаем новый массив, как разницу, где из первого массива исключили все значения второго (А-Б)
findIndex
Возвращает индекс первого элемента, по которому callback вернул true
findLastIndex
Возвращает индекс первого с конца элемента, по которому callback вернул true
first
Возвращает первый или несколько первых элементов массива
flatten
Извлекает, в виде массива, элементы из объектов, содержащихся в передаваемом массиве
indexOf
Возвращает индекс первого совпадающего (===) элемента, если массив сортирован можно ускорить поиск
initial
Возвращает начальную часть массива (кроме n последних)
intersection
Возвращает пересечение массивов (нескольких)
last
Возвращает последний или несколько последних элементов массива
lastIndexOf
Возвращает индекс последнего совпадающего (===) элемента. (можно искать не с самого конца)
pull
Удаляет переданные элементы из массива
range
Создает массив с числами от start до end (можно выбрать шаг)
remove
Удаляет из массива элементы по заданному правилу и возвращает массив удаленных элементов
rest
Возвращает все кроме первого (нескольких первых) элементов массива
sortedIndex
Возвращает индекс вставки текущего значения в сортированном массиве
union
Возвращает массив уникальных значений — результат объединения нескольких массивов
uniq
Создает копию массива без дубликатов
without
Создает новый массив из существующего исключая некоторые значения
xor
Создает новый массив — «семантическую разницу» между переданными массивами
zip
Создает массив сгруппированных в подмассивы элементов. На вход принимает несколько массивов. Собирает так: первые элементы всех входных массивов попадают в первую группу и т.д.
zipObject
Собирает объект из двух массивов (с ключами и со значениями)
Коллекции
at
Создает новую коллекцию, только из перечисленных элементов
contains
Проверяет, содержится (содержатся) ли определенный элемент в коллекции
countBy
Создает объект, ключами которого будут значения, возвращаемые функцией обратного вызова, а значениями — количество соответствующих возвратов
every
Проверка на то, что все элементы коллекции истины (или удовлетворяют условию).
filter
Пробегает по всем элементам коллекции и возвращает МАССИВ из элементов, удовлетворяющих условию
find
Возвращает первый элемент коллекции, отвечающий заданным критериям
findLast
То же самое, что и find, только с конца
forEach
Пробегается по всем элементам коллекции, запуская функцию обратного вызова для каждого элемента
forEachRight
То же самое, что и forEach, только с конца
groupBy
Создает коллекцию, ключами которой являются значения, возвращенные функцией обратного вызова, а значениями — массивы из первоначальных элементов коллекции
indexBy
Создает коллекцию, ключами которой являются значения, возвращенные функцией обратного вызова, а значениями — последние элементы первоначальной коллекции с соответствующим ключом
invoke
Выполняет определенный метод для каждого элемента коллекции и возвращает массив из результатов этого выполнения
map
Создает массив элементов, прогоняя каждый элемент коллекции через функцию обратного вызова
max
Возвращает максимальное значение коллекции
min
Возвращает минимальное значение коллекции
pluck
Возвращает все значения определенного свойства коллекции
reduce
Уменьшаем коллекцию до значения, получаемое вызовом функций обратного вызова для каждого значения. В эту функцию, кроме самого значения, передается также результат предыдущего вызова.
reduceRight
То же самое, что и reduce, только с конца
reject
В противоположность filter — эта функция возвращает массив элементов коллекции, которые не удовлетворяют условию
sample
Возвращает случайный элемент коллекции
shuffle
Возвращает массив из перемешанных в случайном порядке элементов коллекции
size
Возвращает размер коллекции
some
Проверка на то, что хотя бы один элемент коллекции истинен (или удовлетворяет условию).
sortBy
Возвращает массив сортированных по возрастанию элементов коллекции. Для сортировки используются значения получаемые функцией обратного вызова по каждому элементу.
toArray
Преобразует коллекцию к массиву. Полезно для работы с arguments
where
Проводит глубокое сравнение каждого элемента с определенным объектом. Возвращает массив, удовлетворяющий сравнению.
Функции
after
Возвращает функцию, которая вызовет переданный колбек только после n-ого вызова
bind
Возвращает функцию, которая при вызове будет привязана к текущему this, к привязанным аргументам и аргументам, предающимся в саму вызванную функцию.
bindAll
Привязывает все методы объекта к самому этому объекту (this в методах всегда будет сам объект)
bindKey
Привязывает метод объекта к самому объетку (на момент привязки, метод может еще не существовать)
compose
Возвращает функцию — композицию из переданных функций. Передаем f,g,h — возвращает функцию = f(g(h()))
curry
Принимает на вход функцию с n параметрами, а возвращает функцию, которая в случае если параметро достаточно — вызовет входную, если нет, возвратит другую функцию, передав оставшиеся параметры которой — вызовется первоначальная.
debounce
Возвращает функцию, которая запустит входную функцию только выдержав паузу после своего последнего запуска. (устранение дребезжания)
defer
Вызовет входную функцию тогда, когда освободится текущий стек вызова (в начале следующего цикла событий)
delay
Вызовет входную функцию через n миллисекунд
memoize
Возвращает функцию, которая кэширует результаты своего выполнения, и не выполняется, если результат есть в кэше.
once
Возвратит функцию, которая вызовет входную только один раз. В последующие разы будет возвращаться полученный результат.
partial
То же самое, что и bind, но не привязывает this
partialRight
То же самое, что и partial, но привязывается к параметрам справа
throttle
Возвращает функцию, которая вызывает исходную не чаще чем один раз в n миллисекунд
wrap
Создает функцию, в первый параметр которой будет передан первый параметр врапера.
Объекты
assign
Дополняет объект отсутствующими (не просто undefined) свойствами из другого объекта
clone
Делает копию объекта (вложенные объекты копируются по ссылке)
cloneDeep
Глубокое копирование объекта (вложенные объекты копируются по содержанию)
create
Создает объект по переданному прототипу и свойствам
defaults
Дополняет объект отсутствующими (=== undefined) свойствами из другого объекта — задает умолчания
findKey
Ищет первый объект удовлетворяющий условиям — возвращает ключ
findLastKey
Ищет последний объект удовлетворяющий условиям — возвращает ключ
forIn
Обходит все свойства объекта (включая внутренние), вызывая для каждого из них функцию обратного вызова
forInRight
То же самое что и forIn только с конца
forOwn
Обходит все собственные свойства объекта, вызывая для каждого из них функцию обратного вызова
forOwnRight
То же самое что и forOwn только с конца
functions
Возвращает отсортированный массив имен всех свойств объекта, значениями которых ялвяются функции
has
Проверяет, является ли указанное свойство собственным свойством объекта
invert
Создает объект у которого ключи и значения поменяны местами
isArguments
Проверяет, является ли значение — объектом arguments
isArray
Проверяет, является ли значение массивом
isBoolean
Проверяет, является ли значение булевой переменной
isDate
Проверяет, является ли значение массивом
isElement
Проверяет, является ли значение DOM-элементом
isEmpty
Проверяет, является ли значение пустым. Массивы, строки, arguments-объекты с нулевой длинной считаются пустыми
isEqual
Проводит глубокое сравнение двух значений
isFinite
Проверяет, является ли данное значение конечным числом, или же оно может быть приобразовано к нему
isFunction
Проверяет, ялвяется ли данное значение функцией
isNaN
Проверяет значение на === NaN (это не то же самое, что стандартная isNuN, которая возвращает true для undefined и не числовых значений)
isNull
Проверяет значение на === null
isNumber
Проверяет, является ли значение числом (NaN тоже считается числом)
isObject
Проверяет, является ли значение объектом
isPlainObject
Проверяет, является ли значение чистым объектом (созданным конструктором Object)
isRegExp
Проверяет, является ли значение регулярным выражение
isString
Проверяет, является ли значение строкой
isUndefined
Проверяет значение на === undefined
keys
Возвращает массив ключей объекта
mapValues
Созает новый объект с такими же ключами, как у исходного, значения получаются вызовом callback-функции к каждому элементу
merge
Рекурсивно добавляет переданные объекты в объект назначения
omit
Возвращает объект, у которого убраны некоторые свойства
pairs
Создает из объекта двумерный массив, типа [[key1, value1], [key2, value2]].
pick
Создает из объекта другой объект со свойствами из списка
transform
Более простая альтернатива reduce — позволяет трансформировать входящий объект в другой, посредством функции обратного вызова, в которую передается кроме элементов еще и результирующий объект
values
Возвращает массив значений объекта
Утилиты
now
Возвращает текущий Unix-time в миллисекундах
constant
Создает функцию, возвращающую переданное значение
createCallback
Создает функцию, коллбек — используется для внутренних целей lodash
escape
Экранирует символы &, <, >, ", и ' соответсующими html-сущностями
identity
Функция возвращает первый переданный в нее аргумент
mixin
Добавляет в объект (или в сам lodash) элементы преданного объекта. Если объект-приемник — функция, добавляет свойства в прототип.
noConflict
Делает _ равным старому значению (до запуска lodash), и возвращает указатель на lodash
noop
Пустая функция. Возвращает undefined
parseInt
Извлекает число из строки, по умолчанию работает всегда с 10-ой системой счисления (в отличии от стандартной)
property
Возвращает функцию в стиле pluck, вызов которой с объектом в качестве параметра, вернет значение определенного свойства.
random
Вернет случайное число из диапазона. Может дробное.
result
Вернет значение свойства в объекте (если значением будет функция, она будет вызвана и возвращен ее результат)
runInContext
Вернет новую lodash-функцию привязанную к заданному контексту
template
Микрошаблонизатор
times
Выполняет указанный callback n-раз, возвращая массив результатов
unescape
Функция, обратная escape
uniqueId
Возвращает уникальный числовой ID (число, каждый раз на единицу больше. можно передавать префикс)