JavaScript Lodash 工具庫

簡(jiǎn)介

Lodash 提供模塊化、性能和額外功能的現(xiàn)代 JavaScript 實(shí)用工具庫。它通過降低 Array、Number、Objects、String 等等的使用難度從而讓 JavaScript 變得更簡(jiǎn)單,提高開發(fā)者效率。類似的還有 UnderscoreLazy,還有一個(gè) Ramda 庫,它是用柯里化實(shí)現(xiàn)的。

支持情況:Chrome 74-75,F(xiàn)irefox 66-67,IE 11,Edge 18,Safari 11-12 & Node.js 8-12

安裝

CDN:

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>

NPM:

$ npm i lodash

以下將介紹 Loadsh 的常用方法

Find

_.filter 返回一個(gè)新的過濾后的數(shù)組。

var users = [
  { 'user': 'barney', 'age': 36, 'active': true },
  { 'user': 'fred',   'age': 40, 'active': false }
]
 
_.filter(users, (o) => !o.active ) // { 'user': 'fred',   'age': 40, 'active': false }
_.filter(users, { 'age': 36, 'active': true }) // { 'user': 'barney', 'age': 36, 'active': true },
_.filter(users, ['active', false]) // { 'user': 'fred', 'age': 40, 'active': false }
_.filter(users, 'active') // { 'user': 'barney',  'age': 36, 'active': true }

_.find_.findLast 返回匹配元素,否則返回 undefined。

var users = [
  { 'user': 'barney',  'age': 36, 'active': true },
  { 'user': 'fred',    'age': 40, 'active': false },
  { 'user': 'pebbles', 'age': 1,  'active': true }
];
 
_.find(users, (o) => o.age < 40) // { 'user': 'barney',  'age': 36, 'active': true }
_.find(users, { 'age': 1, 'active': true }) // { 'user': 'pebbles', 'age': 1,  'active': true }
_.find(users, ['active', false]) // { 'user': 'fred', 'age': 40, 'active': false }
_.find(users, 'active') // { 'user': 'barney',  'age': 36, 'active': true }


_.findLast([1, 2, 3, 4], (n) => n % 2 == 1) // 3

它們都適用于數(shù)組和對(duì)象。

訪問

_.at 返回選中值的數(shù)組。

_.at([1, 2, 3], 0) // [1]
_.at([1, 2, 3], [0, 1]) // [1, 2]

let object = { 'a': [{ 'b': { 'c': 3 } }, 4] }

_.at(object, ['a[0].b.c', 'a[1]']) // [3, 4]

set/get

set

_.set 返回 object。設(shè)置 object 對(duì)象中對(duì)應(yīng) path 屬性路徑上的值,如果path不存在,則創(chuàng)建。 缺少的索引屬性會(huì)創(chuàng)建為數(shù)組,而缺少的屬性會(huì)創(chuàng)建為對(duì)象。 使用_.setWith 定制path創(chuàng)建。

let object = { 'a': [{ 'b': { 'c': 3 } }] }
 
_.set(object, 'a[0].b.c', 4)
console.log(object.a[0].b.c) // 4
 
_.set(object, ['x', '0', 'y', 'z'], 5)
console.log(object.x[0].y.z) // 5

get

_.get 返回解析的值。根據(jù) object 對(duì)象的 path 路徑獲取值。 如果解析 value 是 undefined 會(huì)以 defaultValue 取代。

let object = { 'a': [{ 'b': { 'c': 3 } }] }

_.get(object, 'a[0].b.c') // 3
_.get(object, ['a', '0', 'b', 'c']) // 3
_.get(object, 'a.b.c', 'default') // 'default'

迭代

_.forEach_.forEachRight 返回集合 collection。

_([1, 2]).forEach(function(value) {
  console.log(value) // 1 2
})
 
_.forEach({ 'a': 1, 'b': 2 }, (value, key) => {
  console.log(key) // a b (不保證迭代順序)
}) 

_.forEachRight([1, 2], function(value) {
  console.log(value) // 2 1.
}) 

_.map 返回新的映射后數(shù)組。

function square(n) {
  return n * n;
}
      
_.map([4, 8], square) // [16, 64]
_.map({ 'a': 4, 'b': 8 }, square) // [16, 64] (不保證迭代順序)

var users = [
  { 'user': 'barney' },
  { 'user': 'fred' }
]

_.map(users, 'user') // ['barney', 'fred']

_.every 如果所有元素經(jīng) predicate(斷言函數(shù)) 檢查后都都返回真值,那么就返回true,否則返回 false。

_.every([true, 1, null, 'yes'], Boolean) // false
 
let users = [
  { 'user': 'barney', 'age': 36, 'active': false },
  { 'user': 'fred',   'age': 40, 'active': false }
]

_.every(users, { 'user': 'barney', 'active': false }) // false
_.every(users, ['active', false]) // true
_.every(users, 'active') // false

Array

_.chunk 返回一個(gè)包含拆分區(qū)塊的新數(shù)組(注:相當(dāng)于一個(gè)二維數(shù)組)。

_.chunk(['a', 'b', 'c', 'd'], 2) // [['a', 'b'], ['c', 'd']]

_.compact 返回過濾掉假值的新數(shù)組。

_.compact([0, 1, false, 2, '', 3]); // [1, 2, 3]

_.fill 返回 array。使用 value 值來填充(替換) array,從start位置開始, 到end位置結(jié)束(但不包含end位置)。

_.fill([1, 2, 3], 'a') // ['a', 'a', 'a']
_.fill(Array(4), 'x') // [ 'x', 'x', 'x', 'x' ]
_.fill([4, 6, 8, 10], '*', 1, 3) // [4, '*', '*', 10]


_.flattenDeep([1, [2, [3, [4]], 5]]); // [1, 2, 3, 4, 5]

_.flatten 返回減少嵌套層級(jí)后的新數(shù)組。

_.flatten([1, [2, [3, [4]], 5]]) // [1, 2, [3, [4]], 5]

_.flattenDeep 返回一個(gè)的新一維數(shù)組。

_.flattenDeep([1, [2, [3, [4]], 5]]) // [1, 2, 3, 4, 5]

過濾

_.drop 返回 array 剩余切片。

_.drop([1, 2, 3]) // [2, 3]
_.drop([1, 2, 3], 2) // [3]
_.drop([1, 2, 3], 5) // []
_.drop([1, 2, 3], 0) // [1, 2, 3]

_.dropRight([1, 2, 3]) // [1, 2]
  • _.take 返回 array 數(shù)組的切片(從起始元素開始n個(gè)元素)。
  • _.takeRight 返回 array 數(shù)組的切片(從結(jié)尾元素開始n個(gè)元素)。
_.take([1, 2, 3])    // [1]
_.take([1, 2, 3], 2) // [1, 2]
_.take([1, 2, 3], 5) // [1, 2, 3]
_.take([1, 2, 3], 0) // []

_.takeRight([1, 2, 3], 2) // [2, 3]

_.slice 返回 數(shù)組 array 裁剪部分的新數(shù)組。

_.slice([1, 2, 3], 0, 2) // [1, 2]

_.initial 返回截取后的數(shù)組array

_.initial([1, 2, 3]) // [1, 2]

_.rest 返回新的函數(shù)。

let say = _.rest(function(what, names) {
  return what + ' ' + _.initial(names).join(', ') +
    (_.size(names) > 1 ? ', & ' : '') + _.last(names)
})
 
say('hello', 'fred', 'barney', 'pebbles') // 'hello fred, barney, & pebbles'

_.dropWhile 返回 array 剩余切片。

_.dropWhile(list, 'active')            // 像過濾器一樣工作
_.dropWhile(list, 'active', true)
_.dropWhile(list, { active: true })
_.dropWhile(list, (n) => ...)
_.dropRightWhile(list, ...)

let users = [
  { 'user': 'barney',  'active': false },
  { 'user': 'fred',    'active': false },
  { 'user': 'pebbles', 'active': true }
]
 
_.dropWhile(users, (o) => !o.active) // { 'user': 'pebbles', 'active': true }
_.dropWhile(users, { 'user': 'barney', 'active': false }) // [{ 'user': 'barney',  'active': false }, {...}]
_.dropWhile(users, ['active', false]) // { 'user': 'pebbles', 'active': true }
_.dropWhile(users, 'active') // [{user: "barney", active: false}, {...}, {...}]

_.without 返回過濾值后的新數(shù)組。

_.without([2, 1, 2, 3], 1, 2) // [3]

_.remove 返回移除元素組成的新數(shù)組。

let array = [1, 2, 3, 4]
let evens = _.remove(array, (n) => {
  return n % 2 == 0;
});
 
console.log(array) // [1, 3]
console.log(evens) // [2, 4]

訪問

_.first 返回?cái)?shù)組 array 的第一個(gè)元素。

_.head([1, 2, 3]) // 1
_.head([]) // undefined

_.last 返回 array 中的最后一個(gè)元素

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

Sets

_.uniq 返回新的去重后的數(shù)組。

_.uniq([2, 1, 2]) // [2, 1]

_.difference 返回一個(gè)過濾值后的新數(shù)組。

_.difference([3, 2, 1], [4, 2]) // [3, 1]

_.intersection 返回一個(gè)包含所有傳入數(shù)組交集元素的新數(shù)組。

_.intersection([2, 1], [4, 2], [1, 2]) // [2]

_.union 返回一個(gè)新的聯(lián)合數(shù)組。

_.union([2], [1, 2]) // [2, 1]

_.concat 返回連接后的新數(shù)組。

let array = [1];
let other = _.concat(array, 2, [3], [[4]])
 
console.log(other) // [1, 2, 3, [4]]
console.log(array) // [1]

Index

_.findIndex_.findLastIndex 返回找到元素的索引值(index),否則返回 -1。

let users = [
  { 'user': 'barney',  'active': false },
  { 'user': 'fred',    'active': false },
  { 'user': 'pebbles', 'active': true }
]

_.findIndex(list, fn)
_.findLastIndex(list, fn)

_.findIndex(users, (o) => o.user == 'barney') // 0
_.findIndex(users, { 'user': 'fred', 'active': false }) // 1
_.findIndex(users, ['active', false]) // 0
_.findIndex(users, 'active') // 2

_.findLastIndex(users, (o) => o.user == 'pebbles') // 2

_.sortedIndex_.sortedLastIndex 返回 value 值應(yīng)該在數(shù)組 array 中插入的索引位置 index。

_.sortedIndex([30, 50], 40) // 1
_.sortedLastIndex([4, 5, 5, 5, 6], 5) // 4

_.indexOf 返回值 value 在數(shù)組中的索引位置,沒有找到為返回-1

_.indexOf([1, 2, 1, 2], 2) // 1
_.indexOf([1, 2, 1, 2], 2, 2) // 3

柯里化(Currying)

返回預(yù)設(shè)參數(shù)的函數(shù)。

let greet = (greeting, name) => `${greeting}, ${name}!`

let fn = _.partial(fn, 'hi')
fn('joe') // 'hi, joe!'

返回新的柯里化(curry)函數(shù)。

_.curry(greet)('hi')         // function(name)
_.curryRight(greet)('joe')   // function(greet)

裝飾器(Decorator)

節(jié)流和防抖

  • _.throttle 返回節(jié)流的函數(shù)。
  • _.debounce 返回防抖的函數(shù)。
_.throttle(fn)
_.debounce(fn)

限制

document.addEventListener('click',  _.before(5, fn)) // 只能調(diào)用5次 
document.addEventListener('click',  _.after(5, fn)) // 5次后才能調(diào)用

const initialize = _.once(fn)
initialize()
initialize() // 類似 _.before(1, fn),只調(diào)用一次 fn

其他

_.wrap 返回新的函數(shù)。

_.wrap(_.escape, (name) => `hi ${name}`) // 與執(zhí)行 name = _.escape(name) 相同

_.delay 返回計(jì)時(shí)器 id 延遲。延遲 wait 毫秒后調(diào)用 fn。 調(diào)用時(shí),任何附加的參數(shù)會(huì)傳給 fn。

_.delay((text) => {
  console.log(text)
}, 2000, 'Hello World!')

_.filter 返回一個(gè)新的過濾后的數(shù)組。

function isEven(n) {
  return n % 2 == 0
}
 
_.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)) // => [1, 3, 5]

_.memoize 返回緩存化后的函數(shù)。

_.memoize(fn)
_.memoize(fn, ...)
          
var object = { 'a': 1, 'b': 2 };
var other = { 'c': 3, 'd': 4 };
 
var values = _.memoize(_.values)
values(object) // => [1, 2]
 
values(other) // => [3, 4]
 
object.a = 2
values(object) // => [1, 2]
 
// 修改結(jié)果緩存。
values.cache.set(object, ['a', 'b'])
values(object) // => ['a', 'b']
 
// 替換 _.memoize.Cache。
_.memoize.Cache = WeakMap

字符串

大寫

轉(zhuǎn)換字符串 string 首字母為大寫,剩下為小寫。

_.capitalize('hello world') // 'Hello world'

轉(zhuǎn)換 string 字符串為 start case。

_.startCase('hello_world') // 'Hello World'

轉(zhuǎn)換字符串 stringsnake case。

_.snakeCase('hello world') // 'hello_world'

轉(zhuǎn)換字符串 stringkebab case。

_.kebabCase('hello world') // 'hello-world'

轉(zhuǎn)換字符串 string駝峰寫法。

_.camelCase('hello world') // 'helloWorld'

填充

_.pad、_.padStart、_.padEnd 返回填充后的字符串。

_.pad('abc', 3)           // 'abc'
_.pad('abc', 8)           // '   abc  '
_.pad('abc', 8, '_-')     // '_-abc_-_'

_.padStart('abc', 3)      // 'abc'
_.padStart('abc', 6)      // '   abc'
_.padStart('abc', 6, '_-')// '_-_abc'

_.padEnd('abc', 3)        // 'abc'
_.padEnd('abc', 6)        // 'abc   '
_.padEnd('abc', 6, '_-')  // 'abc_-_'

去空

string 字符串中移除前面和后面的空格或指定的字符。

_.trim('  str  ')         // 'str' 

string 字符串中移除后面的空格或指定的字符。

_.trimStart('  str  ')     // 'str  '

string 字符串中移除后面的空格或指定的字符。

_.trimEnd('  str  ')    // '  str'
_.trimEnd('-_-abc-_-', '-_-') // '-_-abc'

其他

_.repeat 重復(fù) N 次給定字符串。

_.repeat('-', 2)  // '--'
_.repeat('abc', 2) // 'abcabc'
_.repeat('abc', 0) // ''

轉(zhuǎn)換字符串 string拉丁語-1補(bǔ)充字母拉丁語擴(kuò)展字母-A為基本的拉丁字母,并且去除組合變音標(biāo)記。

_.deburr('déjà vu') // 'deja vu'

截?cái)?string 字符串,如果字符串超出了限定的最大值。 被截?cái)嗟淖址竺鏁?huì)以 omission 代替,omission 默認(rèn)是 "..."。

_.truncate('hello world', 5)   // 'hello...'
_.truncate('hi-diddly-ho there, neighborino', {
  'length': 24,
  'separator': ' '
}) // 'hi-diddly-ho there,...'
 
_.truncate('hi-diddly-ho there, neighborino', {
  'length': 24,
  'separator': /,? +/
}) // 'hi-diddly-ho there...'
 
_.truncate('hi-diddly-ho there, neighborino', {
  'omission': ' [...]'
}) // 'hi-diddly-ho there, neig [...]'

檢查字符串 string 是否以 target 開頭。

_.startsWith('abc', 'a') // true
_.startsWith('abc', 'b') // false
_.startsWith('abc', 'b', 1) // true

檢查字符串 string 是否以給定的 target 字符串結(jié)尾。

_.endsWith('abc', 'c') // true
_.endsWith('abc', 'b') // false
_.endsWith('abc', 'b', 2) // true

對(duì)象

鍵值

  • _.keys 返回包含屬性名的數(shù)組。創(chuàng)建一個(gè) object 的自身可枚舉屬性名為數(shù)組。
  • _.values 返回對(duì)象屬性的值的數(shù)組。創(chuàng)建 object 自身可枚舉屬性的值為數(shù)組。
_.keys(obj) 
_.values(obj)

function Foo() {
  this.a = 1
  this.b = 2
}
 
Foo.prototype.c = 3

_.keys(new Foo) // ['a', 'b'] (無法保證遍歷的順序)
_.keys('hi') // ['0', '1']

_.values(new Foo) // [1, 2] (無法保證遍歷的順序)
_.values('hi') // ['h', 'i']

鏈?zhǔn)秸{(diào)用

Loadsh 跟 jQuery 一樣支持鏈?zhǔn)秸{(diào)用

_([1, 2, 3])
  .map((n) => n * n)
  .tap(console.log)
  .thru((n) => n.reverse())
  .value()

支持鏈?zhǔn)秸{(diào)用的方法

支持鏈?zhǔn)秸{(diào)用的方法

不支持鏈?zhǔn)秸{(diào)用的方法

不支持鏈?zhǔn)秸{(diào)用的方法

關(guān)于 Ramda 的教程可以查看阮一峰老師的 Ramda 函數(shù)庫參考教程。

NPM:npm install ramda
CDN:

<script src="https://cdn.jsdelivr.net/npm/ramda@latest/dist/ramda.min.js"></script>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容