Jump to content

Underscore.js

Разработчик(и) Джереми Ашкенас , Джулиан Гонгриджп
Первоначальный выпуск 28 октября 2009 г .; 14 лет назад ( 28.10.2009 ) [1]
Стабильная версия
1.13.6 / 24 сентября 2022 г .; 22 месяца назад ( 24.09.2022 )
Репозиторий
Написано в JavaScript
Размер Производство 7,5 КБ
68 КБ разработки
Тип библиотека JavaScript
Лицензия С
Веб-сайт подчеркнутый .org

Underscore.js — это библиотека JavaScript , предоставляющая служебные функции для распространенных задач программирования. [2] Он сравним с функциями, предоставляемыми Prototype.js и языком Ruby , но в нем используется дизайн функционального программирования вместо расширения прототипов объектов . В документации Underscore.js называется «связующим звеном со jQuery смокингом и подтяжками Backbone.js ». Underscore.js был создан Джереми Ашкенасом , который также известен своими Backbone.js и CoffeeScript . [3]

Джереми Ашкенас создал Underscore к концу 2009 года как ответвление проекта DocumentCloud вместе с Backbone.js . Это была одна из первых библиотек для JavaScript, предоставляющая общие утилиты функционального программирования, вдохновленная Prototype.js , Functional JavaScript Оливера Стила и Micro-Templating Джона Резига. [4]

В 2012 году Джон-Дэвид Далтон создал форк Underscore под названием Lo-Dash (ныне Lodash ). Первоначально Lo-Dash рекламировался как альтернатива Underscore с «последовательностью, настройкой, производительностью и дополнительными возможностями». [5] Тем не менее, Lodash уже на ранней стадии отошел от оригинального интерфейса Underscore. [6] и начал вносить более радикальные изменения в выпуске 3.0.0, в результате чего пользователям Lodash пришлось менять свой код. [7]

В мае 2015 года Джереми Ашкенас объявил, что Джон-Дэвид Далтон связался с ним по поводу объединения библиотек. Несмотря на опасения по поводу стиля и размера кода, Ашкенас не был против объединения некоторых расширений Lodash с Underscore. [8] В то время несколько разработчиков параллельно работали над Underscore и Lodash; эта группа участников начала вносить изменения в Underscore, чтобы сделать его более похожим на Lodash. [9]

Однако параллельно с этими усилиями Далтон внес более радикальные изменения в интерфейс Lodash. В июне 2015 года он анонсировал версию Lodash 4.0.0, которая еще больше отдалила Lodash от интерфейса Underscore, а также значительно отклонилась от серии версии 3.x самого Lodash. [10] [11] Это побудило некоторые проекты, зависевшие от Lodash, создать свои собственные дистрибутивы Lodash 3. [12]

В феврале 2016 года Далтон объявил, что считает слияние завершенным. Он предложил пользователям перейти с Underscore на Lodash, мотивируя это статистикой доли использования. [13] Однако сопровождающий Underscore ясно дал понять, что не намерен прекращать разработку Underscore как отдельной библиотеки. [14] После 2016 года обе библиотеки вошли в состояние низкой активности развития. [15] [16]

Со временем в новые версии стандарта ECMAScript были добавлены встроенные функции, которые копируют некоторые функции Underscore, такие как Object.assign и Array.prototype.map. Однако встроенные функции иногда менее эффективны, чем их эквиваленты Underscore; в частности, встроенные методы итерации массива, такие как map, filter и forEach не может перебирать простые объекты и не поддерживает сокращения итерируемых . [17] [18] [19] [20] [21] [22]

По состоянию на март 2021 года Underscore активно разрабатывает Джулиан Гонгриджп, который начал вносить значительный вклад в марте 2020 года. [15] Библиотека по-прежнему широко используется, и ее загружают с npm несколько миллионов раз каждую неделю. [23]

Содержание

[ редактировать ]

По сути, Underscore обеспечивает три вещи:

  1. Коллекция из более чем 100 повторно используемых функций, которые призваны быть практически полезными в повседневных приложениях. В документации различают несколько категорий:
    • Функции сбора, такие как find, map, min/ max, groupBy и shuffle обрабатывать коллекции данных. Эти функции могут работать как с элементами массивоподобных последовательностей, так и со свойствами объектов.
    • Функции массива, такие как first/ last, flatten, chunk и zip работать исключительно с объектами, подобными массивам.
    • Функциональные функции, такие как bind, memoize, partial и debounce принять функцию в качестве аргумента и вернуть новую функцию с измененными свойствами ( функции высшего порядка ).
    • Функции объекта — это более фундаментальная категория, содержащая множество функций, которые также повторно используются внутри Underscore. [24] Его можно условно разделить на две подкатегории:
      • Функции типового тестирования, такие как isNumber, isElement и isDataView.
      • Такие функции, как keys, extend, pick/ omit, pairs и invert, которые манипулируют (простыми) объектами как данными.
    • Функции полезности — это категория отдыха. Среди прочего, он включает тривиальные функции identity и noop и функции манипулирования строками escape, unescape и template. В эту категорию также входят функции iteratee и mixin, которые можно считать специальными объектами, как указано в пункте 2.
  2. Специальные помещения, такие как chain и iteratee, которые объединяются с функциями из пункта 1, чтобы обеспечить более короткий и понятный синтаксис. Специальная функция _, в честь которого названа библиотека, занимает центральное место в этих учреждениях.
  3. Грамотный исходный код, предназначенный для чтения, чтобы можно было легко отслеживать реализацию библиотеки. Документация включает визуализированную версию исходного кода, где комментарии находятся слева, а логика — справа. Комментарии форматируются с использованием Markdown , а логика имеет подсветку синтаксиса . Начиная с версии 1.11, Underscore является модульным . По этой причине документация теперь включает как модульную версию аннотированного исходника, в которой каждая функция находится на отдельной странице, так и import Ссылки представляют собой кликабельные гиперссылки и единственную версию для чтения , где все функции находятся на одной странице в порядке зависимости .

Обзор и примеры функций

[ редактировать ]

Подчеркивание продвигает функциональный стиль , в котором несколько функций могут быть объединены в одном выражении для получения новой функциональности. Например, в следующем выражении используются две функции подчеркивания для группировки слов по первым символам:

import { groupBy, first } from 'underscore';

groupBy(['avocado', 'apricot', 'cherry', 'date', 'durian'], first);

// result:
// { a: ['avocado', 'apricot'],
//   c: ['cherry'],
//   d: ['date', 'durian']
// }

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

import { groupBy } from 'underscore';

const first = array => array[0];

groupBy(['avocado', 'apricot', 'cherry', 'date', 'durian'], first);

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

Функции, которые перебирают содержимое массива или объекта, обычно принимают данные в качестве первого параметра, а итерирующую функцию или итерируемого объекта — в качестве второго параметра. В приведенном выше примере first передается ли итерируемый объект groupBy.

Хотя от итератора не требуется их использовать, в большинстве случаев он получает три аргумента: (1) значение в текущей позиции в коллекции, (2) ключ или индекс этого значения и (3) всю коллекцию. В следующем примере второй аргумент используется в итерации для pick чтобы выбрать только свойства объекта, ключ которого начинается с заглавной буквы:

import { pick } from 'underscore';

const details = {
    Official: 'Wolfgang Amadeus Mozart',
    informal: 'Wolfie'
};
const keyIsUpper = (value, key) => key[0] === key[0].toUpperCase();

pick(details, keyIsUpper);
// {Official: 'Wolfgang Amadeus Mozart'}

Многие функции Underscore можно использовать в качестве итерации, как показано ранее на примере first. Кроме того, есть несколько распространенных случаев, когда пользователь может избежать написания итеративной функции, используя вместо этого сокращенную итерируемую функцию . В следующем примере строка 'name' используется как сокращение для итерации, чтобы извлечь все name свойства из массива объектов:

import { map } from 'underscore';

const people = [
    {name: 'Lily', age: 44, occupation: 'librarian'},
    {name: 'Harold', age: 10, occupation: 'dreamer'},
    {name: 'Sasha', age: 68, occupation: 'library developer'}
];

map(people, 'name');  // ['Lily', 'Harold', 'Sasha']

Все функции категории «коллекция», включая groupBy и map функции, продемонстрированные выше, могут перебирать как индексы массива, так и ключи объекта. Это показано ниже с помощью reduce:

import { reduce } from 'underscore';

const add = (a, b) => a + b;
const sum = numbers => reduce(numbers, add, 0);

sum([11, 12, 13]);                  // 36
sum({Alice: 9, Bob: 9, Clair: 7});  // 25

Помимо функций, которые перебирают массивы или объекты, Underscore предоставляет широкий спектр других функций многократного использования. Например, throttle ограничивает частоту, с которой оценивается функция:

import { throttle } from 'underscore';

// The scroll event triggers very often, so the following line may
// slow down the browser.
document.body.addEventListener('scroll', expensiveUpdateFunction);

// Limit evaluation to once every 100 milliseconds.
const throttledUpdateFunction = throttle(expensiveUpdateFunction, 100);

// Much smoother user experience!
document.body.addEventListener('scroll', throttledUpdateFunction);

Другой пример: defaults, который присваивает свойства объекта, только если они еще не установлены:

import { defaults } from 'underscore';

const requestData = {
    url: 'wikipedia.org',
    method: 'POST',
    body: 'article text'
};
const defaultFields = {
    method: 'GET',
    headers: {'X-Requested-With': 'XMLHttpRequest'}
};

defaults(requestData, defaultFields);
// {
//     url: 'wikipedia.org',
//     method: 'POST',
//     body: 'article text',
//     headers: {'X-Requested-With': 'XMLHttpRequest'}
// }

The _ функция

[ редактировать ]

Подчеркивание получило свое название от функции _, который служит нескольким целям.

Функция-обертка

[ редактировать ]

Как функция, _ возвращает завернутую версию любого значения, переданного в качестве первого аргумента. Этот специальный объект имеет все функции Underscore в качестве методов, что позволяет использовать другую нотацию, называемую «стилем ООП»:

import _, { last } from 'underscore';

// "Normal" or "functional" style
last([1, 2, 3]); // 3

// "OOP style"
_([1, 2, 3]).last() // 3

Эта функция используется при цепочке ( следующий раздел ). Значение можно снова развернуть с помощью .value() метод для дальнейшей обработки за пределами Underscore. В некоторых случаях значения также разворачиваются автоматически.

// Explicit unwrap
_([1, 2, 3]).value()  // [1, 2, 3]

// Automatic unwrap when coerced to number
1 + _(2)  // 3

// Automatic unwrap when coerced to string
'abc' + _('def')  // 'abcdef'

// Automatic unwrap when formatted as JSON
JSON.stringify({ a: _([1, 2]) })  // '{"a":[1,2]}'

Частичный заполнитель приложения

[ редактировать ]

_ также выступает в качестве заполнителя для partial функция. partial создает частично примененную версию функции и _ можно использовать, чтобы оставить некоторые параметры «открытыми», чтобы их можно было указать позже. Например, groupBy Пример из обзора можно расширить следующим образом, чтобы превратить выражение в функцию многократного использования:

import _, { partial, groupBy, first } from 'underscore';

const groupByFirstChar = partial(groupBy, _, first);

groupByFirstChar(['avocado', 'apricot', 'cherry', 'date', 'durian']);
// { a: ['avocado', 'apricot'],
//   c: ['cherry'],
//   d: ['date', 'durian']
// }

groupByFirstChar(['chestnut', 'pistache', 'walnut', 'cashew']);
// { c: ['chestnut', 'cashew'],
//   p: ['pistache'],
//   w: ['walnut]
// }

Точка настройки

[ редактировать ]

Более того, _ служит центральной точкой настройки , где пользователи могут настроить поведение функций Underscore в соответствии со своими потребностями. В частности, пользователи могут переопределить _.iteratee для создания новых сокращений итеративных элементов и _.templateSettings для того, чтобы настроить template функция.

Дескриптор пространства имен

[ редактировать ]

В более общем плане все функции подчеркивания присутствуют как свойства на _, например, также _.map и _.debounce. Это дает возможность использовать _ как дескриптор пространства имен . С появлением модулей в ES6 наличие такого дескриптора пространства имен больше не является строго необходимым, но такая практика по-прежнему часто встречается в коде, использующем старые модульные системы, такие как AMD и CommonJS :

var _ = require('underscore');

_.groupBy(['avocado', 'apricot', 'cherry', 'date', 'durian'], _.first);

Учитывая существующую практику, это также может быть удобной записью, чтобы уточнить, что имеется в виду функция именно из библиотеки Underscore, а не функция с таким же именем из другой библиотеки. Например, и Underscore, и Async предоставляют функцию с именем each; чтобы различать их, можно написать _.each и async.each, соответственно.

Функция chain может использоваться для создания модифицированной версии оболочки, созданной _ функция . При вызове такой связанной оболочки каждый метод возвращает новую обертку, чтобы пользователь мог продолжать обрабатывать промежуточные результаты с помощью функций Underscore:

import { chain } from 'underscore';

const square = x => x * x;
const isOdd = x => x % 2;

chain([1, 2, 3, 4]).filter(isOdd).map(square).last()
// returns a wrapper of 9

Нередко функция, реализованная с помощью Underscore, полностью состоит из return утверждение с цепочкой, заканчивающейся на .value():

const add = (x, y) => x + y;

// Given an array of numbers, return the sum of the squares of
// those numbers. This could be used in a statistics library.
function sumOfSquares(numbers) {
    return chain(numbers)
        .map(square)
        .reduce(add)
        .value();
}

Объединение в цепочки не является исключительным для функций, поставляемых с Underscore. Пользователи также могут включить цепочку для своих собственных функций, передав их в mixin функция:

import { reduce, mixin } from 'underscore';

const sum = numbers => reduce(numbers, add, 0);

mixin({ sum, square });

chain([1, 2, 3]).map(square).sum().value();  // 14
chain([1, 2, 3]).sum().square().value();     // 36

Фактически, именно так цепочка включается и для собственных функций Underscore. Все функции Underscore пишутся как обычные автономные функции, без какой-либо специальной подготовки к связыванию, а затем «примешиваются» к _ функционировать впоследствии. [25]

Итеративные сокращения

[ редактировать ]

Как упоминалось ранее в обзоре , большинство функций Underscore, которые перебирают массивы или объекты, принимают сокращенную запись как итерируемый, а не функцию. Повторяем пример из этого раздела здесь:

import { map } from 'underscore';

const people = [
    {name: 'Lily', details: {age: 44, occupation: 'fire fighter'}},
    {name: 'Harold', details: {age: 10, occupation: 'dreamer'}},
    {name: 'Sasha', details: {age: 68, occupation: 'library developer'}}
];

map(people, 'name');  // ['Lily', 'Harold', 'Sasha']

На самом деле эта запись активируется путем передачи сокращенного значения через _.iteratee чтобы получить функцию. _.iteratee по умолчанию используется iteratee функция, которая поставляется с подчеркиванием, которое, в зависимости от значения, возвращает функцию следующим образом.

Если значение представляет собой строку, iteratee пересылает значение в property, который интерпретирует строку как ключ свойства. Он возвращает функцию, которая пытается извлечь свойство с заданным ключом из своего аргумента. Следующие выражения эквивалентны:

import { iteratee, property } from 'underscore';

map(people, 'name');
map(people, iteratee('name'));
map(people, property('name'));
map(people, obj => obj && obj['name']);
// ['Lily', 'Harold', 'Sasha']

Массивы и числа также передаются в property. Массивы можно использовать для получения вложенных свойств:

map(people, ['details', 'occupation']);
// ['fire fighter', 'dreamer', 'library developer']

Числа могут использоваться как индексы массивов и строк. Объединив все это, мы можем использовать следующее выражение, чтобы подсчитать, сколько раз буквы алфавита встречаются в качестве второго символа профессии человека:

import { countBy } from 'underscore';

countBy(people, ['details', 'occupation', 1]);  // {i: 2, r: 1}

Хэши атрибутов

[ редактировать ]

Когда значение является объектом, iteratee пересылает его matcher, который интерпретирует объект как набор атрибутов, которые должны быть сопоставлены. Он возвращает функцию, которая вернет true или false в зависимости от того, имеет ли его аргумент тот же набор атрибутов.

import { find } from 'underscore';

find(people, {name: 'Sasha'});
// {name: 'Sasha', details: {age: 68, occupation: 'library developer'}}

find(people, {name: 'Walter'});
// undefined

null и undefined

[ редактировать ]

Когда значение null или undefined, iteratee возвращает функцию идентификации , которую Underscore экспортирует как identity. Это можно использовать для фильтрации истинных значений из коллекции:

import { filter, iteratee, identity } from 'underscore';

const example = [0, 1, '', 'abc', true, false, {}];

// The following expressions are all equivalent.
filter(example);
filter(example, undefined);
filter(example, iteratee(undefined));
filter(example, identity);
// [1, 'abc', true, {}]

Переопределение _.iteratee

[ редактировать ]

Пользователи могут переопределить _.iteratee для создания собственных сокращений. Следующий пример иллюстрирует, как это можно использовать для реализации фильтрации регулярных выражений:

import {
    iteratee as originalIteratee,
    isRegExp,
    mixin,
    filter,
} from 'underscore';

function iteratee(value, context) {
    if (isRegExp(value)) {
        return string => value.test(string);
    } else {
        return originalIteratee(value, context);
    }
}

mixin({iteratee});

filter(['absolutely', 'amazing', 'fabulous', 'trousers'], /ab/);
// ['absolutely', 'fabulous']

См. также

[ редактировать ]
  1. ^ Версия 0.1.0 , jashkenas/underscore, GitHub
  2. ^ «Underscore.js — небольшой фреймворк с акцентом» . entwicklung.de (на немецком языке). 20 июня 2018 г. Проверено 9 июля 2020 г.
  3. ^ «JavaScript Meetup City» , открытое издание , The New York Times , 4 апреля 2012 г.
  4. ^ Ашкенас, Джереми. «Подчеркнуть источник 0.4.0» . cdn.rawgit.com . Проверено 1 марта 2021 г.
  5. ^ «Ло-Дэш v2.2.1» . lodash.com . Архивировано из оригинала 6 ноября 2013 года . Проверено 1 марта 2021 г. {{cite web}}: CS1 maint: неподходящий URL ( ссылка )
  6. ^ «Журнал изменений Lodash — 1.0.0 rc1» . github.com . 4 декабря 2012 года . Проверено 1 марта 2021 г.
  7. ^ «Журнал изменений Лодаша — 3.0.0» . github.com . 26 января 2015 года . Проверено 1 марта 2021 г.
  8. ^ Ашкенас, Джереми (21 мая 2015 г.). «Большая Кахуна: тема слияния Underscore + Lodash» . github.com . Проверено 1 марта 2021 г.
  9. ^ «Подчеркивание: объединенные запросы на включение с критическими изменениями в период с 21 мая по 1 октября 2015 г.» . github.com . Проверено 1 марта 2021 г.
  10. ^ Далтон, Джон-Дэвид (8 июня 2015 г.). «комментарий к «Core API» » . github.com . Проверено 1 марта 2021 г.
  11. ^ «Журнал изменений Lodash 4.0.0» . github.com . 12 января 2016 года . Проверено 1 марта 2021 г.
  12. ^ "@sailshq/lodash" . npmjs.com . Проверено 1 марта 2021 г.
  13. ^ Далтон, Джон-Дэвид (13 февраля 2016 г.). «Объединить обновление» . github.com . Проверено 1 марта 2021 г.
  14. ^ Кребс, Адам (17 февраля 2016 г.). «прокомментируйте «Объединить обновление». " . github.com . Проверено 1 марта 2021 г.
  15. ^ Перейти обратно: а б "jashkenas/подчеркивание. Информация: участники" . github.com . Проверено 1 марта 2021 г.
  16. ^ "lodash/lodash Insight: Участники" . github.com . Проверено 1 марта 2021 г.
  17. ^ «Массив.прототип.карта» . http://developer.mozilla.org . Проверено 1 марта 2021 г.
  18. ^ «Массив.прототип.фильтр» . http://developer.mozilla.org . Проверено 1 марта 2021 г.
  19. ^ "Array.prototype.forEach" . http://developer.mozilla.org . Проверено 1 марта 2021 г.
  20. ^ "_.карта" . underscorejs.org . Проверено 1 марта 2021 г.
  21. ^ "_.фильтр" . underscorejs.org . Проверено 1 марта 2021 г.
  22. ^ "_.каждый" . underscorejs.org . Проверено 1 марта 2021 г.
  23. ^ «подчеркивание» . npmjs.com . Проверено 1 марта 2021 г.
  24. ^ Гонгриджп, Джулиан. "модули/index.js" . underscorejs.org . Проверено 5 марта 2021 г.
  25. ^ Гонгриджп, Джулиан. «модули/index-default.js» . underscorejs.org . Проверено 4 марта 2021 г.
[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: ed4d54252ce1fd045bcb75d24f89a496__1698398220
URL1:https://arc.ask3.ru/arc/aa/ed/96/ed4d54252ce1fd045bcb75d24f89a496.html
Заголовок, (Title) документа по адресу, URL1:
Underscore.js - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)