Lodash - 前端开发常用函数库
数组方法 (Array)
- .findIndex(array, [predicate=.identity], [fromIndex=0]) [查找索引]
- 找到数组中predicate断言为true的第一个数组元素索引,未找到返回-1.
- 如果要从数组末尾开始查找则使用:.findLastIndex(array, [predicate=.identity], [fromIndex=array.length-1])
_.findIndex(users, function(o) { return o.user == 'barney'; });
_.findIndex(users, { 'user': 'fred', 'active': false });
- _.indexOf(array, value, [fromIndex=0]) [查找索引]
- 找到数组中和value相等的第一个元素索引,未找到返回-1
- 如果要从数组末尾开始查找则使用: _.lastIndexOf(array, value, [fromIndex=array.length-1])
_.indexOf([1, 2, 1, 2], 2); // => 1
_.lastIndexOf([1, 2, 1, 2], 2); // => 3
- _.sortedIndexOf(array, value)[查找索引]
- 在已排序的数组中利用二分查找,查找给定值的最低索引值
- 在已排序数组中,查找给定值的最高索引:_.sortedLastIndexOf(array, value)
_.sortedIndexOf([4, 5, 5, 5, 6], 5); // => 1
_.sortedLastIndexOf([4, 5, 5, 5, 6], 5); // => 3
- _.sortedIndex(array, value) [查找索引]
- 根据二分查找,为保证数组已有的排序,寻找给定数值能够插入的位置最低索引。
- 为保证数组已有的排序,寻找给定数值能够插入的位置最高索引:_.sortedLastIndex(array, value)
- 根据迭代函数调用结果确定排序位置的的最低索引:.sortedIndexBy(array, value, [iteratee=.identity])
- 根据迭代函数调用结果确定排序位置的的最高索引:.sortedLastIndexBy(array, value, [iteratee=.identity])
_.sortedIndex([30, 50], 40); // => 1
_.sortedLastIndex([4, 5, 5, 5, 6], 5); // => 4
var objects = [{ 'x': 4 }, { 'x': 5 }];
_.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); // => 0
// The `_.property` iteratee shorthand.
_.sortedIndexBy(objects, { 'x': 4 }, 'x'); // => 0
var objects = [{ 'x': 4 }, { 'x': 5 }];
_.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); // => 1
// The `_.property` iteratee shorthand.
_.sortedLastIndexBy(objects, { 'x': 4 }, 'x'); // => 1
- _.first(array) [返回指定索引元素]
- 返回数组元素的第一个元素, 别名:_.head(array)
_.first([1, 2, 3]);
// => 1
- _.last(array) [返回指定索引元素]
- 返回数组的最后一个元素
_.last([1, 2, 3]);
// => 3
- _.nth(array, [n=0]) [返回指定索引元素]
- 返回数组指定索引的元素,指定负数则从数组末尾算起
var array = ['a', 'b', 'c', 'd'];
_.nth(array, 1); // => 'b'
_.nth(array, -2); // => 'c';
- _.initial(array) [返回不包含指定元素的新数组]
- 返回除了最后一个元素的所有元素的新数组
_.initial([1, 2, 3]);
// => [1, 2]
- _.tail(array) [返回不包含指定元素的新数组]
- 创建一个数组的切片,返回不包含第一个元素的其他所有元素。
_.tail([1, 2, 3]);
// => [2, 3]
- _.without(array, [values]) [返回不包含指定元素的新数组]
- 返回不包含指定元素,创建新的数组返回。
_.without([2, 1, 2, 3], 1, 2);
// => [3]
- _.slice(array, [start=0], [end=array.length]) [返回包含指定索引的新数组]
- 创建一个数组的的切片,不包含end索引指定的元素。
- _.take(array, [n=1]) [返回包含指定索引的新数组]
- 创建一个数组的切片,返回从开头开始的n个元素,默认为第一个元素。
- 若要创建从末尾开始的n个元素的数组切片,则使用_.takeRight(array, [n=1])
_.take([1, 2, 3]); // => [1]
_.take([1, 2, 3], 2); // => [1, 2]
_.takeRight([1, 2, 3]); // => [3]
_.takeRight([1, 2, 3], 2); // => [2, 3]
- .takeWhile(array, [predicate=.identity]) [返回包含指定索引的新数组]
- 返回断言函数为true的元素直到false为止的数组的切片。
- 若要从数组末尾开始迭代,则使用_.takeRightWhile(array, [predicate=_.identity])
var users = [
{ 'user': 'barney', 'active': false },
{ 'user': 'fred', 'active': false },
{ 'user': 'pebbles', 'active': true }
];
_.takeWhile(users, function(o) { return !o.active; });
// => objects for ['barney', 'fred']
// The `_.property` iteratee shorthand.
_.takeWhile(users, 'active'); // => []
_.takeRightWhile(users, function(o) { return !o.active; });
// => objects for []
// The `_.property` iteratee shorthand.
_.takeRightWhile(users, 'active');
// => objects for ['pebbles']
- _.drop(array, [n=1]) [返回不包含指定索引的新数组]
- 从数组开头开始删除n个元素,将余下的元素作为新数组返回
- 如果从数组末尾开始删除n个元素,则使用: _.dropRight(array, [n=1])
_.drop([1, 2, 3]); // => [2, 3]
_.drop([1, 2, 3], 2); // => [3]
_.dropRight([1, 2, 3]); // => [1, 2]
_.dropRight([1, 2, 3], 2); // => [1]
- .dropWhile(array, [predicate=.identity]) [返回不包含指定索引的新数组]
- 从数组开头开始删除元素,直到断言函数返回false时停止删除
- 如果从数组末尾开始删除,则使用:.dropRightWhile(array, [predicate=.identity])
var users = [
{ 'user': 'barney', 'active': false },
{ 'user': 'fred', 'active': false },
{ 'user': 'pebbles', 'active': true }
];
_.dropWhile(users, function(o) { return !o.active; });
// => objects for ['pebbles']
// The `_.matches` iteratee shorthand.
_.dropWhile(users, { 'user': 'barney', 'active': false });
// => objects for ['fred', 'pebbles']
- _.compact(array) [去除多余的数组元素返回新数组]
- 去除数组中的无效数据,返回新的数组。 需要注意:0,false 都会视为无效数据
_.compact([0, 1, false, 2, '', 3, null, undefined, NaN]);
// => [1, 2, 3]
- _.uniq(array) [去除多余的数组元素返回新数组]
- 数组元素去重
- 若要根据调用迭代函数后的结果去重,则使用:.uniqBy(array, [iteratee=.identity])
- 若要自定义比较函数,则使用:_.uniqWith(array, [comparator])
_.uniq([2, 1, 2]); // => [2, 1]
_.uniqBy([2.1, 1.2, 2.3], Math.floor); // => [2.1, 1.2]
// The `_.property` iteratee shorthand.
_.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); // => [{ 'x': 1 }, { 'x': 2 }]
var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
_.uniqWith(objects, _.isEqual);
// => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]
- _.fill(array, value, [start=0], [end=array.length]) [数组内容变换]
- 用指定的值填充数组,可以传递开始索引和结束索引,填充值不包含填充结束索引的值
var array = [1, 2, 3];
_.fill(array, 'a');
// => ['a', 'a', 'a']
_.fill([4, 6, 8, 10], '*', 1, 3);
// => [4, '*', '*', 10]
- _.reverse(array)[数组内容变换]
反转数组中的元素,基于数组自身的reverse方法实现,此方法修改数组本身
var array = [1, 2, 3];
_.reverse(array);
// => [3, 2, 1]
console.log(array);
// => [3, 2, 1]
- _.join(array, [separator=',']) [数据结构变形]
- 将数组转换为由分割符连接在一起的字符串
_.join(['a', 'b', 'c'], '~');
// => 'a~b~c'
- _.chunk(array, [size=1]) [数据结构变形]
- 将数组按照指定的大小进行分块
_.chunk(['a', 'b', 'c', 'd'], 2);
// => [['a', 'b'], ['c', 'd']]
_.chunk(['a', 'b', 'c', 'd'], 3);
// => [['a', 'b', 'c'], ['d']]
- _.flatten(array) [数据结构变形]
- 将数组展平一层深度,需要递归展平所有嵌套数组,则使用:_.flattenDeep(array)
- 如果要展平指定的深度,则使用:_.flattenDepth(array, [depth=1])
_.flatten([1, [2, [3, [4]], 5]]);
// => [1, 2, [3, [4]], 5]
_.flattenDeep([1, [2, [3, [4]], 5]]);
// => [1, 2, 3, 4, 5]
var array = [1, [2, [3, [4]], 5]];
_.flattenDepth(array, 2);
// => [1, 2, 3, [4], 5]
- _.zip([arrays]) [数据结构变形]
- 创建一个分组的数组集合,数组的第一个元素为一组,第二个元素为一组,第n个元素为一组。
- 要进一步处理,分组后的值,则使用:.zipWith([arrays], [iteratee=.identity])
_.zip(['a', 'b'], [1, 2], [true, false]);
// => [['a', 1, true], ['b', 2, false]]
_.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) {
return a + b + c;
});
// => [111, 222]
- _.unzip(array) [数据结构变形]
- 接受一个分组元素数组,并创建一个数组,将元素重新组合为其压缩前的配置。
- 如果进一步处理分组后的元素,则使用:.unzipWith(array, [iteratee=.identity])
var zipped = _.zip([1, 2], [10, 20], [100, 200]);
// => [[1, 10, 100], [2, 20, 200]]
_.unzip(zipped);
// => [[1, 2], [10, 20], [100, 200]]
_.unzipWith(zipped, _.add);
// => [3, 30, 300]
- _.zipObject([props=[]], [values=[]]) [数据结构变形]
- 接受两个数组,将其组合为一个对象,
- 第一个数组接受path路径则使用:_.zipObjectDeep([props=[]], [values=[]])
_.zipObject(['a', 'b'], [1, 2]);
// => { 'a': 1, 'b': 2 }
_.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]);
// => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } }
- _.fromPairs(pairs) [数据结构变形]
- 将键值数组对,转换为对象
_.fromPairs([['a', 1], ['b', 2]]);
// => { 'a': 1, 'b': 2 }
- _.concat(array, [values]) [合并数组值]
- 将数组或者其他类型值与已知的数组连接在一起, 从而创建一个新数组返回。
var array = [1];
var other = _.concat(array, 2, [3], [[4]]);
console.log(other);
// => [1, 2, 3, [4]]
console.log(array);
// => [1]
- _.union([arrays]) [创建数组的并集]
- 创建多个数组的并集,按顺序返回唯一值的数组。
- 若要比较迭代后的值进行并集处理,则使用:.unionBy([arrays], [iteratee=.identity])
- 若要自定义比较函数,则使用:_.unionWith([arrays], [comparator])
_.union([2], [1, 2]);
// => [2, 1]
_.unionBy([2.1], [1.2, 2.3], Math.floor);
// => [2.1, 1.2]
// The `_.property` iteratee shorthand.
_.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
// => [{ 'x': 1 }, { 'x': 2 }]
var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
_.unionWith(objects, others, _.isEqual);
// => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
- _.intersection([arrays]) [找出多个数组的交集]
- 找出所有数组的交集,即存在于给定的每一个数组中的元素,组成的新数组。
- 如果要找出处理后数组的元素交集:使用_.intersectionBy([arrays], [iteratee=_.identity])
- 如果要自定义指定比较函数:使用_.intersectionWith([arrays], [comparator])
_.intersection([2, 1], [2, 3]);
// => [2]
_.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor);
// => [2.1]
// The `_.property` iteratee shorthand.
_.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x');
// => [{ 'x': 1 }]
var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
_.intersectionWith(objects, others, _.isEqual);
// => [{ 'x': 1, 'y': 2 }]
- _.xor([arrays]) [找出多个数组的差集]
- 对多个数组执行差集,并返回新的数组
- 对数组执行迭代函数,根据结果返回差集的新数组:.xorBy([arrays], [iteratee=.identity])
- 自定义比较函数,对多个数组执行差集:_.xorWith([arrays], [comparator])
_.xor([2, 1], [2, 3]); // => [1, 3]
_.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor); // => [1.2, 3.4]
// The `_.property` iteratee shorthand.求数组的差集
_.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); // => [{ 'x': 2 }]
var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }];
_.xorWith(objects, others, _.isEqual);
// => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }]
- _.difference(array, [values]) [找出一个数组相对于另一个数组不在其中的元素]
- 找出第一个数组不在第二个数组中的值,并作为一个新数组返回
- 如果要对查找的数据进行处理后再进行查找则使用:.differenceBy(array, [values], [iteratee=.identity])
- 如果要自定义查找比较逻辑则使用:_.differenceWith(array, [values], [comparator])
_.difference([2, 1], [2, 3]);
// => [1]
_.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor);
// => [1.2]
// The `_.property` iteratee shorthand.
_.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x');
// => [{ 'x': 2 }]
var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
_.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
// => [{ 'x': 2, 'y': 1 }]
- _.pull(array, [values]) [删除指定的元素,原数组被修改]
- 从数组中删除指定的元素数据, 此方法修改原数组,
- 如果用数组指定要删除的元素则使用方法:.pullAll(array, values),此方法类似于.difference,但不会修改原数组
- 如果要删除调用迭代函数处理过的比较元素则使用:.pullAllBy(array, values, [iteratee=.identity])
- 如果要自定义删除时比较相等的方法则使用:_.pullAllWith(array, values, [comparator])
var array = ['a', 'b', 'c', 'a', 'b', 'c'];
_.pull(array, 'a', 'c');
console.log(array); // => ['b', 'b']
_.pullAll(array, ['a', 'c']);
console.log(array);// => ['b', 'b']
var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
_.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
console.log(array); // => [{ 'x': 2 }]
var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }];
_.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual);
console.log(array);// => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }]
- _.pullAt(array, [indexes]) [返回删除的元素,原数组被修改]
- 删除指定索引的元素,并返回删除的元素,原数组同时也被修改。
var array = ['a', 'b', 'c', 'd'];
var pulled = _.pullAt(array, [1, 3]);
console.log(array); // => ['a', 'c']
console.log(pulled); // => ['b', 'd']
- .remove(array, [predicate=.identity]) [返回删除的元素,原数组被修改]
根据断言函数返回true删除数组中的元素,结果返回删除的元素,原数组被修改。
var array = [1, 2, 3, 4];
var evens = _.remove(array, function(n) {
return n % 2 == 0;
});
console.log(array); // => [1, 3]
console.log(evens); // => [2, 4]
集合方法(Array | Object | String)
- find(collection:Array|Object, [predicate=.identity],[fromIndex=0])
- 找到集合中符合preidcate断言的第一个数据,未找到返回undefined
- 从右向左查找使用:.findLast(collection, [predicate=.identity], [fromIndex=collection.length-1])
var users = [
{ 'user': 'barney', 'age': 36, 'active': true },
{ 'user': 'fred', 'age': 40, 'active': false },
{ 'user': 'pebbles', 'age': 1, 'active': true }
];
_.find(users, function(o) { return o.age < 40; });
_.find(users, { 'age': 1, 'active': true });
_.findLast([1, 2, 3, 4], function(n) {
return n % 2 == 1;
});
// => 3
- .filter(collection:Array|Object, [predicate=.identity])
- 对数据集合进行过滤返回断言为true的元素集合,
- 如果想返回断言为false的元素集合,不用修改断言逻辑可以直接使用_.reject(collection, [predicate=_.identity])
var users = [
{ 'user': 'barney', 'age': 36, 'active': true },
{ 'user': 'fred', 'age': 40, 'active': false }
];
_.filter(users, function(o) { return !o.active; }); // => objects for ['fred']
// The `_.matches` iteratee shorthand.
_.filter(users, { 'age': 36, 'active': true }); // => objects for ['barney']
- .map(collection:Array|Object, [iteratee=.identity])
对数据集合每个元素调用迭代器,返回调用结果,函数最终得到包含调用结果的新数组
_.map([4, 8], (value)=> value * value); // => [16, 64]
var users = [{ 'user': 'barney' }, { 'user': 'fred' }];
// The `_.property` iteratee shorthand.
_.map(users, 'user'); // => ['barney', 'fred']
- .reduce(collection:Array|Object, [iteratee=.identity], [accumulator])
- 给定一个初始值,然后对集合中的元素进行累计,返回的数据作为新的累计元素初始值,迭代结束后返回最终的累计值。
- 从右向左迭代使用:.reduceRight(collection, [iteratee=.identity], [accumulator])
_.reduce([1, 2], function(sum, n) {
return sum + n;
}, 0); // => 3
// => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
_.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
(result[value] || (result[value] = [])).push(key);
return result;
}, {});
- .forEach(collection: Array|Object, [iteratee=.identity])
- 迭代集合中的元素,可以通过return false及早中断迭代。
- 从右向左迭代:.forEachRight(collection, [iteratee=.identity])
_.forEach([1, 2], function(value) {
console.log(value);
}); // => Logs `1` then `2`.
_.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
console.log(key);
}); // => Logs 'a' then 'b' (iteration order is not guaranteed).
_.forEachRight([1, 2], function(value) {
console.log(value);
});
// => Logs `2` then `1`.
- .every(collection: Array|Object, [predicate=.identity])
迭代集合中的元素如果每个元素的迭代断言为true,则最终结果为true,否则有一个为false,会提早结束迭代并返回false
_.every([true, 1, null, 'yes'], Boolean); // => false
- .some(collection: Array|Object, [predicate=.identity])
迭代集合中的元素,如果有一个元素的迭代断言返回true,则最终结果为true,并提前结束迭代,否则继续迭代直到所有断言返回false,
则最终结果返回false。
_.some([null, 0, 'yes', false], Boolean); // => true
- .groupBy(collection:Array|Object, [iteratee=.identity])
对集合数据进行分组,返回一个对象,对象的key是迭代器返回的结果,value是具有相同调用结果的所有集合元素。
_.groupBy([6.1, 4.2, 6.3], Math.floor); // => { '4': [4.2], '6': [6.1, 6.3] }
// The `_.property` iteratee shorthand.
_.groupBy(['one', 'two', 'three'], 'length'); // => { '3': ['one', 'two'], '5': ['three'] }
- .countBy(collection:Array|Object, [iteratee=.identity])
对集合数据进行分组统计,返回一个对象,对象key是迭代器返回的结果,value是具有相同返回结果的次数统计。
_.countBy([6.1, 4.2, 6.3], Math.floor); // => { '4': 1, '6': 2 }
// The `_.property` iteratee shorthand.
_.countBy(['one', 'two', 'three'], 'length'); // => { '3': 2, '5': 1 }
- _.includes(collection: Array|Object|string, value, [fromIndex=0])
判断一个值是否在集合中
_.includes([1, 2, 3], 1); // => true
_.includes({ 'a': 1, 'b': 2 }, 1); // => true
_.includes('abcd', 'bc'); // => true
- .flatMap(collection: Array|Object, [iteratee=.identity])
- 类似_.map 的功能,但_.flatMap 会将迭代结果为数组的数据在最终返回的新数组中展平。
_.flatMap([1, 2], (n) => [n, n]); // => [1, 1, 2, 2]
- .flatMapDeep(collection: Array|Object, [iteratee=.identity])
- 类似_.flatMap的功能,但会递归地展平迭代结果,最终得到展平后的新数组,
- 若要指定展平层级,使用_.flatMapDepth(collection, iteratee, n)
_.flatMapDeep([1, 2], (n) => [[[n, n]]]); // => [1, 1, 2, 2]
- _.invokeMap(collection: Array|Object, path, [args])
- 迭代调用collection中path指定的方法,path 为函数时则迭代调用函数,并最终返回新的数组集合
- 调用path指定集合对象中的方法
const users = [
{ name: 'Alice', greet: function() { return `Hello, I'm ${this.name}`; } },
{ name: 'Bob', greet: function() { return `Hello, I'm ${this.name}`; } }
];
const greetings = _.invokeMap(users, 'greet');
console.log(greetings);
// 输出: ['Hello, I'm Alice', 'Hello, I'm Bob']
- 调用数组的原生方法,并传递参数
const numbers = [1, 2, 3];
const squaredNumbers = _.invokeMap(numbers, 'toFixed', 2);
console.log(squaredNumbers);
// 输出: ['1.00', '2.00', '3.00']
- .keyBy(collection:Array|Object, [iteratee=.identity])
通过调用迭代器生成键,迭代的元素作为value,最终返回一个对象。
var array = [{ 'dir': 'left', 'code': 97 }, { 'dir': 'right', 'code': 100 } ];
_.keyBy(array, 'dir');
// => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
- .orderBy(collection: Array|Object, [iteratees=[.identity]], [orders])
- 对集合对象进行排序, 迭代器为一个数组集合,orders 指定每一个迭代器的排序为升序还是降序。
var users = [
{ 'user': 'fred', 'age': 48 },
{ 'user': 'barney', 'age': 34 },
{ 'user': 'fred', 'age': 40 },
{ 'user': 'barney', 'age': 36 }
];
// Sort by `user` in ascending order and by `age` in descending order.
_.orderBy(users, ['user', 'age'], ['asc', 'desc']);
// => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
- .sortBy(collection: Array|Object, [iteratees=[.identity]])
- 创建一个元素数组,该数组通过将集合中的每个元素传递给每个迭代器的结果按升序排序。
- 此方法执行稳定排序,即它保留相等元素的原始排序顺序。迭代器使用一个参数调用:(值)。
- 如果需要进行降序排列使用: _.orderBy
var users = [
{ 'user': 'fred', 'age': 48 },
{ 'user': 'barney', 'age': 36 },
{ 'user': 'fred', 'age': 40 },
{ 'user': 'barney', 'age': 34 }
];
_.sortBy(users, [function(o) { return o.user; }]);
// => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]]
_.sortBy(users, ['user', 'age']);
// => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]]
- .partition(collection: Array|Object, [predicate=.identity])
- 通过迭代断言将集合中的元素分为两组,数组第一个元素集合为迭代断言为true的数组集合,第二个数组元素集合为迭代断言为false数组的集合。
var users = [
{ 'user': 'barney', 'age': 36, 'active': false },
{ 'user': 'fred', 'age': 40, 'active': true },
{ 'user': 'pebbles', 'age': 1, 'active': false }
];
_.partition(users, {'active': false}); // => objects for [['barney', 'pebbles'], ['fred']]
- _.size(collection: Array|Object|string)
- 获取集合的大小
_.size([1, 2, 3]); // => 3
_.size({ 'a': 1, 'b': 2 }); // => 2
_.size('pebbles'); // => 7
- _.sample(collection: Array|Object)
- 从集合中获取一个随机元素
- 从集合中获取n个元素: _.sampleSize(collection, [n=1])
_.sample([1, 2, 3, 4]);
// => 2
- _.shuffle(collection: Array|Object)
- 使用一种洗牌算法打乱集合中的值
_.shuffle([1, 2, 3, 4]);
// => [4, 1, 3, 2]
对象方法(Object)
- _.get(object, path, [defaultValue])
- 获取对象路径的值,如果为undefined, 则返回给定默认值
var object = { 'a': [{ 'b': { 'c': 3 } }] };
_.get(object, 'a[0].b.c'); // => 3
_.get(object, 'a.b.c', 'default'); // => 'default'
- _.result(object, path, [defaultValue])
- 与_.get 类似,只是path上是函数的时候会调用函数,返回调用结果
var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };
_.result(object, 'a[0].b.c1'); // => 3
_.result(object, 'a[0].b.c2'); // => 4
_.result(object, 'a[0].b.c3', 'default'); // => 'default'
- _.invoke(object, path, [args])
- 在对象的路径上调用方法
var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] };
_.invoke(object, 'a[0].b.c.slice', 1, 3); // => [2, 3]
- _.set(object, path, value)
- 修改或者创建指定的对象路径上的值
- 若要定制创建路径对象使用_.setWith(object, path, value, [customizer])
var 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
var object = {};
_.setWith(object, '[0][1]', 'a', Object);
// => { '0': { '1': 'a' } }
- _.unset(object, path)
- 删除对象路径上的属性
var object = { 'a': [{ 'b': { 'c': 7 } }] };
_.unset(object, 'a[0].b.c');
// => true
console.log(object);
// => { 'a': [{ 'b': {} }] };
- _.update(object, path, updater)
- 修改对象路径中的值,并使用修改函数updater产生修改值。
- 若要定义生成的路径对象则使用:_.updateWith(object, path, updater, [customizer])
var object = { 'a': [{ 'b': { 'c': 3 } }] };
_.update(object, 'a[0].b.c', function(n) { return n * n; });
console.log(object.a[0].b.c);
// => 9
var object = {};
_.updateWith(object, '[0][1]', _.constant('a'), Object);
// => { '0': { '1': 'a' } }
- .findKey(object, [predicate=.identity])
- 类型_.find 但是它返回断言函数为true的第一个元素的key值。
var users = {
'barney': { 'age': 36, 'active': true },
'fred': { 'age': 40, 'active': false },
'pebbles': { 'age': 1, 'active': true }
};
_.findKey(users, { 'age': 1, 'active': true });
// => 'pebbles'
- _.at(oject, [paths])
- 根据指定的对象路径,返回一个由value值组成的数组集合。
var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
_.at(object, ['a[0].b.c', 'a[1]']); // => [3, 4]
- _.pick(object, [paths]
- 根据指定的path集合,创建一个新的对象
- 根据断言函数返回true的迭代的属性,创建新的对象:.pickBy(object, [predicate=.identity])
var object = { 'a': 1, 'b': '2', 'c': 3 };
_.pick(object, ['a', 'c']); // => { 'a': 1, 'c': 3 }
var object = { 'a': 1, 'b': '2', 'c': 3 };
_.pickBy(object, _.isNumber); // => { 'a': 1, 'c': 3 }
- _.omit(object, [paths])
- 它是_.pick 的反方法,忽略掉指定的path,返回由剩余字段组成的新的对象。
- 根据断言函数忽略掉返回true的属性,剩余的属性组成新的对象: .omitBy(oject, [predicate=.identity])
var object = { 'a': 1, 'b': '2', 'c': 3 };
_.omit(object, ['a', 'c']); // => { 'b': '2' }
var object = { 'a': 1, 'b': '2', 'c': 3 };
_.omitBy(object, _.isNumber); // => { 'b': '2' }
- _.keys(object)
- 创建一个自身可枚举的对象的属性组成的数组,
- 如果包括继承属性的键则使用_.keysIn(object)
function Foo() {
this.a = 1;
this.b = 2;
}
Foo.prototype.c = 3;
_.keys(new Foo); // => ['a', 'b'] (iteration order is not guaranteed)
- _.values(object)
- 创建一个自身可枚举的由对象值组成的数组,
- 如果包括继成属性值则使用_.valuesIn(object)
function Foo() {
this.a = 1;
this.b = 2;
}
Foo.prototype.c = 3;
_.values(new Foo); // => [1, 2] (iteration order is not guaranteed)
- _.assign(object, [sources])
- 此方法等同于Object.assign, 将sources对象合并到Object对象,只合并自身可枚举属性,
- 若要包括继承属性使用_.assignIn(object, [sources])
function Foo() { this.a = 1; }
function Bar() { this.c = 3; }
Foo.prototype.b = 2;
Bar.prototype.d = 4;
_.assign({ 'a': 0 }, new Foo, new Bar); // => { 'a': 1, 'c': 3 }
- _.assignWith(object, sources, [customizer])
- 此方法类似_.assign, 但它接受一个定制函数,由定制函数决定如何产生分配的值。
- 若要处理包括继承的属性则使用_.assignInWith(object, sources, [customizer])
function customizer(objValue, srcValue) {
return _.isUndefined(objValue) ? srcValue : objValue;
}
var defaults = _.partialRight(_.assignWith, customizer);
defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); // => { 'a': 1, 'b': 2 }
- _.defaults(object, [sources])
- 此方法类似于_.assignIn, 但差别在于只合并object中属性值为undefined,即不存在的属性值,如果object中属性已有值包括空字符串,则不会进行覆盖。
- 递归地对属性值为对像进一步处理使用:_.defaultsDeep(object, [sources])
_.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); // => { 'a': 1, 'b': 2 }
_.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } }); // => { 'a': { 'b': 2, 'c': 3 } }
- _.merge(object, [sources])
- 此方法类似于_.assignIn, 但会递归地处理自身属性和继承属性值为对象和数组的情况,默认跳过source对象属性值为undefine的情况,其他类型值会直接覆盖。
var object = { 'a': [{ 'b': 2 }, { 'd': 4 }] };
var other = { 'a': [{ 'c': 3 }, { 'e': 5 }] };
_.merge(object, other); // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
- _.mergeWith(object, sources, customizer)
- 此方法类似于_.merge,但它接受一个定制函数,由函数决定如何生成合并结果,如果返回undefined,则由_.mergeWith决定合并的值。
function customizer(objValue, srcValue) {
if (_.isArray(objValue)) {
return objValue.concat(srcValue);
}
}
var object = { 'a': [1], 'b': [2] };
var other = { 'a': [3], 'b': [4] };
_.mergeWith(object, other, customizer); // => { 'a': [1, 3], 'b': [2, 4] }
- .forIn(object, [iteratee=.identity])
- 相当于for in 语句,循环遍历对象自身属性和继承属性, return false可以提前结束遍历
function Foo() { this.a = 1; this.b = 2; }
Foo.prototype.c = 3;
_.forIn(new Foo, function(value, key) {
console.log(key);
}); // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
- .forOwn(object, [iteratee=.identity])
- 相当于for in 语句,但只遍历对象自身可枚举属性,不需要使用Object.hasOwnProperty进行判断,return false可以提前结束遍历
function Foo() { this.a = 1; this.b = 2; }
Foo.prototype.c = 3;
_.forOwn(new Foo, function(value, key) {
console.log(key);
}); // => Logs 'a' then 'b' (iteration order is not guaranteed).
- _.invert(object)
反转属性和值,生成新的对象,如果反转后有相同的属性则,后面的会覆盖前面的。
var object = { 'a': 1, 'b': 2, 'c': 1 };
_.invert(object); // => { '1': 'c', '2': 'b' }
- .invertBy(object, [iteratee=.identity])
与_.invert不同的是反转后,会将具有相同属性的值组成一个数组,而不是进行覆盖,并且可以接受一个迭代函数返回定制的属性。
var object = { 'a': 1, 'b': 2, 'c': 1 };
_.invertBy(object); // => { '1': ['a', 'c'], '2': ['b'] }
_.invertBy(object, function(value) {
return 'group' + value;
});
// => { 'group1': ['a', 'c'], 'group2': ['b'] }
- .mapValues(object, [iteratee=.identity])
- 迭代处理对象,返回与原对象具有相同键的新对象。
var users = {
'fred': { 'user': 'fred', 'age': 40 },
'pebbles': { 'user': 'pebbles', 'age': 1 }
};
_.mapValues(users, function(o) { return o.age; }); // => { 'fred': 40, 'pebbles': 1 }
// The `_.property` iteratee shorthand.
_.mapValues(users, 'age'); // => { 'fred': 40, 'pebbles': 1 }
- .mapKeys(object, [iteratee=.identity])
- 与_.mapValues 相反,它会返回与原对象具有相同值的新对象,key则有迭代函数生成。
_.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
return key + value;
}); // => { 'a1': 1, 'b2': 2 }
- _.functions(object)
- 提取对象当中值为函数的所有属性名到一个数组当中返回,如果要包括继承的属性,则使用_.functionsIn(object)
function Foo() {
this.a = _.constant('a');
this.b = _.constant('b');
}
Foo.prototype.c = _.constant('c');
_.functions(new Foo); // => ['a', 'b']
- _.has(object, path)
- 检查path路径是否是对象当中自身可访问属性,
- 要检查继承属性路径,则使用_.hasIn(object, path)
var object = { 'a': { 'b': 2 } };
var other = _.create({ 'a': _.create({ 'b': 2 }) });
_.has(object, 'a'); // => true
_.has(object, 'a.b'); // => true
_.has(other, 'a'); // => false
- _.create(prototype, [properties])
- 此方法等同于Object.create,创建一个新对象,其基于某个对象作为原型继承其属性,并可以添加其他对象属性到新创建的对象中。
function Shape() { this.x = 0; this.y = 0; }
function Circle() { Shape.call(this); }
Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle });
var circle = new Circle; circle instanceof Circle; // => true
- _.toPairs(object)
别名: _.entries(object)
- 此方法等同于Object.entries, 将对象的属性和值以数组以数组的形式返回,通常用于迭代语法 for of 循环
其与_.fromPairs相反,将属性和值的数组对集合转换为对象
function Foo() { this.a = 1; this.b = 2; }
Foo.prototype.c = 3;
_.toPairs(new Foo); // => [['a', 1], ['b', 2]] (iteration order is not guaranteed)
- .transform(object, [iteratee=.identity], [accumulator])
- 类似于_.reduce, 但具有更多特性,可以根据object的数据类型自动创建初始累计值,可通过return false进行中断,
也可以转换结构等进行复杂操作。
_.transform([2, 3, 4], function(result, n) {
result.push(n *= n);
return n % 2 == 0;
}, []);
// => [4, 9]
_.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
(result[value] || (result[value] = [])).push(key);
}, {});
// => { '1': ['a', 'c'], '2': ['b'] }
链式调用方法
- _(value)
创建一个lodash实例,包装值并隐式启用方法链序列方法,
检索单个值或可能返回基本类型值的方法将自动结束链式调用序列并返回解包后的值。
否则,必须使用 _#value 来解包该值。
function square(n) {
return n * n;
}
var wrapped = _([1, 2, 3]);
// Returns an unwrapped value.
wrapped.reduce(_.add);
- .chain(value)
创建一个lodash实例,并包装值,启用显式的方法链调用,最后必须用#value 解包
var users = [
{ 'user': 'barney', 'age': 36 },
{ 'user': 'fred', 'age': 40 },
{ 'user': 'pebbles', 'age': 1 }
];
var youngest = _
.chain(users)
.sortBy('age')
.map(function(o) {
return o.user + ' is ' + o.age;
})
.head()
.value();
// => 'pebbles is 1'
- _.tap(value, interceptor)
此方法调用拦截器并返回值。拦截器使用一个参数(值)进行调用。此方法的目的是 “介入” 方法链序列,以便修改中间结果。
_([1, 2, 3])
.tap(function(array) {
// Mutate input array.
array.pop();
})
.reverse()
.value();
// => [2, 1]
- _.thru(value, interceptor)
此方法与 _.tap 类似,不同之处在于它返回拦截器的结果。此方法的目的是在方法链式调用序列中 “传递” 值,替换中间结果。
_(' abc ')
.chain()
.trim()
.thru(function(value) {
return [value];
})
.value();
// => ['abc']
- _.prototype.commit()
执行链序列并返回包装后的结果。
var array = [1, 2];
var wrapped = _(array).push(3);
console.log(array);
// => [1, 2]
wrapped = wrapped.commit();
console.log(array);
// => [1, 2, 3]
wrapped.last();
// => 3
- _.prototype.plant(value)
创建一个链序列种植值的克隆,将其作为包装值。
function square(n) {
return n * n;
}
var wrapped = _([1, 2]).map(square);
var other = wrapped.plant([3, 4]);
other.value();
// => [9, 16]
wrapped.value();
// => [1, 4]
7._.prototype.value()
执行链序列以解析未包装的值。
_([1, 2, 3]).value();
// => [1, 2, 3]
语言相关工具方法
- _.cloneDeep(value)
- 递归地进行深拷贝
- 自定义拷贝的结果:_.cloneDeepWith(value, [customizer])
var objects = [{ 'a': 1 }, { 'b': 2 }];
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false
- _.isEqual(value, other)
- 对两个值进行深度比较,判断它们是否相等
- 自定义比较结果实用:_.isEqualWith(value, other, [customizer])
- _.isMatch(object, source)
- 检测对象object中是否包含source的的所有属性值。
var object = { 'a': 1, 'b': 2 };
_.isMatch(object, { 'b': 2 });
// => true
_.isMatch(object, { 'b': 1 });
// => false
- _.conformsTo(object, source)
- 使用object对象的属性值调用source对象中相对应属性的断言函数,检查对象是否符合源。
var object = { 'a': 1, 'b': 2 };
_.conformsTo(object, { 'b': function(n) { return n > 1; } });
// => true
_.conformsTo(object, { 'b': function(n) { return n > 2; } });
// => false
- _.isEmpty(value)
- 检查给定值是否为空值,包括:空字符串,空数组,空对象,需要注意:它会将数字0,true,false,也会认为是空值。
- _.isArray(value)
- 检查值是否是一个数组
- _.isNumber(value)
- 检查值是否是基本数字类型或对象
- _.isString(value)
- 检查值是否是字符串基本类型或对象
- _.isFunction(value)
- 检查值是否是一个函数对象
- _.isInteger(value)
- 检查值是否是一个整数
- _.isPlainObject(value)
- 检查值是否为普通对象
- _.isError(value)
- 检查值是否是一个Error对象或其子对象
- _.isNaN(value)
- 检查值是否是NaN
- _.isNil(value)
- 检查值是否是null 或 undefined
- _.toArray(value)
- 将值转化为数组
_.toArray({ 'a': 1, 'b': 2 });
// => [1, 2]
_.toArray('abc');
// => ['a', 'b', 'c']
_.toArray(1);
// => []
- _.toInteger(value)
- 将值转为整型
_.toInteger(3.2);
// => 3
_.toInteger('3.2');
// => 3
- _.toNumber(value)
- 将值转为数字类型
_.toNumber('3.2');
// => 3.2
- _.toString(value)
- 将值转换为字符串, null 和 undefined都将被转为空字符串
_.toString(null);
// => ''
_.toString(-0);
// => '-0'
_.toString([1, 2, 3]);
// => '1,2,3'
工具方法
- _.flow([funcs])
- 将多个函数组合成一个函数,前一个函数的调用结果作为后一个函数的参数。
function square(n) {
return n * n;
}
var addSquare = _.flow([_.add, square]);
addSquare(1, 2);
// => 9
- .times(n, [iteratee=.identity])
- 调用迭代函数 n 次,返回每次调用结果组成的数组。迭代函数会传入一个参数:(索引)。
_.times(3, String); // => ['0', '1', '2']
_.times(4, _.constant(0)); // => [0, 0, 0, 0]
- _.uniqueId([prefix=''])
- 生成一个唯一的 ID。如果提供了前缀,则将 ID 附加到该前缀之后。
_.uniqueId('contact_'); // => 'contact_104'
_.uniqueId(); // => '105'
- _.range([start=0], end, [step=1])
- 创建一个数字数组(正数和 / 或负数),该数组从 start 开始递增,但不包括 end。
- 如果指定了负数 start 但未指定 end 或 step,则使用 -1 作为步长。
- 如果未指定 end,则将其设置为 start,然后将 start 设置为 0。
_.range(4); // => [0, 1, 2, 3]
_.range(-4); // => [0, -1, -2, -3]
_.range(1, 5); // => [1, 2, 3, 4]
_.range(1, 5); // => [1, 2, 3, 4]
_.range(0, 20, 5); // => [0, 5, 10, 15]
_.range(0, -4, -1); // => [0, -1, -2, -3]
_.range(1, 4, 0); // => [1, 1, 1]
_.range(0); // => []
- _.mixin([object=lodash], source, [options={}])
- 将源对象所有可枚举的字符串键函数属性添加到目标对象。如果对象是一个函数,那么方法也会添加到其原型上,默认添加到lodash上。
function vowels(string) {
return _.filter(string, function(v) {
return /[aeiou]/i.test(v);
});
}
_.mixin({ 'vowels': vowels });
_.vowels('fred'); // => ['e']
_('fred').vowels().value(); // => ['e']
- _.attempt(func, [args])
- 尝试调用函数 func,返回结果或捕获到的错误对象。调用 func 时,任何其他参数都会提供给它。
// Avoid throwing errors for invalid selectors.
var elements = _.attempt(function(selector) {
return document.querySelectorAll(selector);
}, '>_>');
if (_.isError(elements)) {
elements = [];
}
- _.bindAll(object, methodNames)
- 将对象的方法绑定到对象本身,覆盖现有方法。
var view = {
'label': 'docs',
'click': function() {
console.log('clicked ' + this.label);
}
};
_.bindAll(view, ['click']);
jQuery(element).on('click', view.click);
// => Logs 'clicked docs' when clicked.
- .over([iteratees=[.identity]])
- 创建一个函数,该函数使用接收到的参数调用迭代器,并返回它们的结果。
var func = _.over([Math.max, Math.min]);
func(1, 2, 3, 4); // => [4, 1]
- .overEvery([predicates=[.identity]])
- 创建一个函数,该函数用于检查所有断言函数在使用接收到的参数调用时是否都返回真值。
var func = _.overEvery([Boolean, isFinite]);
func('1'); // => true
func(null); // => false
- .overSome([predicates=[.identity]])
- 创建一个函数,该函数用于检查在使用接收到的参数调用时,是否有任何断言函数返回真值。
var func = _.overSome([Boolean, isFinite]);
func('1'); // => true
func(null); // => true
- _.constant(value)
- 创建一个返回值的函数
var objects = _.times(2, _.constant({ 'a': 1 }));
console.log(objects); // => [{ 'a': 1 }, { 'a': 1 }]
console.log(objects[0] === objects[1]); // => true
- _.defaultTo(value, defaultValue)
- 检查值以确定是否应返回默认值来代替它。如果值为 NaN、null 或 undefined,则返回默认值。
_.defaultTo(1, 10); // => 1
_.defaultTo(undefined, 10); // => 10
高阶函数创建
- _.before(n, func)
- 创建一个函数,该函数调用 func,并使用创建的函数的 this 绑定和参数,前提是调用次数少于 n 次。
对创建的函数的后续调用将返回最后一次 func 调用的结果。
- _.after(n, func)
- 与 _.before 相反;此方法创建一个函数,该函数在被调用 n 次或更多次后调用 func 。
- _.bind(func, thisArg, [partials])
创建一个函数,该函数使用 thisArg 的 this 绑定调用 func,并将 partials 前置到它接收的参数中。
function greet(greeting, punctuation) {
return greeting + ' ' + this.user + punctuation;
}
var object = { 'user': 'fred' };
var bound = _.bind(greet, object, 'hi');
bound('!');
// => 'hi fred!'
// Bound with placeholders.
var bound = _.bind(greet, object, _, '!');
bound('hi');
// => 'hi fred!'
- _.bindKey(object, key, [partials])
创建一个函数,该函数调用对象 [key] 处的方法,并将偏函数前置到它接收到的参数之前。
var object = {
'user': 'fred',
'greet': function(greeting, punctuation) {
return greeting + ' ' + this.user + punctuation;
}
};
var bound = _.bindKey(object, 'greet', 'hi');
bound('!');
// => 'hi fred!'
object.greet = function(greeting, punctuation) {
return greeting + 'ya ' + this.user + punctuation;
};
- _.curry(func, [arity=func.length])
- 创建一个函数,该函数接受 func 参数,并且如果至少提供了 arity 数量的参数,则调用 func 并返回其结果;
- 否则返回一个函数,该函数接受剩余的 func 参数,依此类推。如果 func.length 不足,可以指定 func 的元数。
- 从右向左传参,考虑使用:_.curryRight(func, [arity=func.length])
var abc = function(a, b, c) {
return [a, b, c];
};
var curried = _.curry(abc);
curried(1)(2)(3);
// => [1, 2, 3]
curried(1, 2)(3);
// => [1, 2, 3]
curried(1, 2, 3);
// => [1, 2, 3]
// Curried with placeholders.
curried(1)(_, 3)(2);
// => [1, 3, 2]
- _.partial(func, [partials])
- 创建一个函数,该函数在调用 func 时,会将 partials 前置到它接收到的参数之前。此方法类似于 _.bind,但它不会改变 this 绑定。
function greet(greeting, name) {
return greeting + ' ' + name;
}
var sayHelloTo = _.partial(greet, 'hello');
sayHelloTo('fred');
// => 'hello fred'
// Partially applied with placeholders.
var greetFred = _.partial(greet, _, 'fred');
greetFred('hi');
// => 'hi fred'
- _.debounce(func, [wait=0], [options={}])
- 创建一个防抖函数,该函数会延迟调用 func,直到自上次调用防抖函数以来已过了 wait 毫秒。
- 防抖函数带有一个 cancel 方法,用于取消延迟的 func 调用,以及一个 flush 方法,用于立即调用它们。
- 提供选项以指示是否应在等待超时的开始和 / 或结束时调用 func。
- func 使用提供给防抖函数的最后参数调用。对防抖函数的后续调用将返回最后一次 func 调用的结果。
- 如果前置和后置选项都为 true,则仅当在等待超时期间被防抖的函数被调用超过一次时,才会在超时的后置阶段调用 func 。
- 如果wait为 0 且leading为false,函数调用将被推迟到下一个时机,类似于设置超时时间为 0 的setTimeout。
- [options.leading=false](布尔值):指定在超时的起始边界调用。
- [options.maxWait](数字):在调用func之前,允许func延迟的最长时间。
- [options.trailing=true](布尔值):指定在超时的结束时刻调用。
// Avoid costly calculations while the window size is in flux.
jQuery(window).on('resize', _.debounce(calculateLayout, 150));
// Invoke `sendMail` when clicked, debouncing subsequent calls.
jQuery(element).on('click', _.debounce(sendMail, 300, {
'leading': true,
'trailing': false
}));
- _.throttle(func, [wait=0], [options={}])
- 创建一个节流函数,该函数在每 wait 毫秒内最多调用一次 func。
- 节流函数带有一个 cancel 方法来取消延迟的 func 调用,以及一个 flush 方法来立即调用它们。
- 提供选项以指示是否应在 wait 超时的开始和 / 或结束时调用 func。
- func 使用提供给节流函数的最后参数调用。对节流函数的后续调用将返回最后一次 func 调用的结果。
- 如果前置和后置选项都为真,那么仅当节流函数在等待超时期间被调用超过一次时,才会在超时的后沿调用func。
- 如果wait为 0 且leading为false,函数调用将被推迟到下一个时间点,类似于设置了超时时间为 0 的setTimeout 。
- [options.leading=true](布尔值):指定在超时的起始边界调用。
- [options.trailing=true](布尔值):指定在超时的结束时刻调用。
// Avoid excessively updating the position while scrolling.
jQuery(window).on('scroll', _.throttle(updatePosition, 100));
// Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
jQuery(element).on('click', throttled);
// Cancel the trailing throttled invocation.
jQuery(window).on('popstate', throttled.cancel);
- _.delay(func, wait, [args])
- 在等待指定的毫秒数后调用 func。调用 func 时,任何额外的参数都会传递给它。
_.delay(function(text) {
console.log(text);
}, 1000, 'later');
// => Logs 'later' after one second.
- _.memoize(func, [resolver])
- 创建一个函数,该函数会记忆化
func
的结果。 - 如果提供了
resolver
,它将根据提供给记忆化函数的参数确定用于存储结果的缓存键。 - 默认情况下,提供给记忆化函数的第一个参数将用作映射缓存键。
func
将使用记忆化函数的this
绑定进行调用。 - 缓存通过被记忆化函数的
cache
属性公开。可以通过用一个实例实现了clear
、delete
、get
、has
和set
这些Map
方法接口的构造函数替换_.memoize.Cache
构造函数,来定制其创建过程。
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]
// Modify the result cache.
values.cache.set(object, ['a', 'b']);
values(object); // => ['a', 'b']
// Replace `_.memoize.Cache`.
_.memoize.Cache = WeakMap;
- _.negate(predicate)
创建一个函数,该函数对断言函数 predicate 的结果取反。
function isEven(n) {
return n % 2 == 0;
}
_.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); // => [1, 3, 5]
- _.once(func)
- 创建一个函数,该函数被限制只能调用一次 func。
- 对该函数的重复调用将返回第一次调用的结果。
- func 会使用创建的函数的 this 绑定和参数进行调用。
- .overArgs(func, [transforms=[.identity]])
- 创建一个函数,该函数使用转换后的参数调用func。
function doubled(n) {
return n * 2;
}
function square(n) {
return n * n;
}
var func = _.overArgs(function(x, y) {
return [x, y];
}, [square, doubled]);
func(9, 3); // => [81, 6]
func(10, 5); // => [100, 10]
- _.spread(func, [start=0])
创建一个函数,该函数使用 create 函数的 this 绑定以及类似于 Function#apply 的参数数组来调用 func。
var say = _.spread(function(who, what) {
return who + ' says ' + what;
});
say(['fred', 'hello']); // => 'fred says hello'
数字处理
- _.clamp(number, [lower], upper)
将数字限制在包含下限和上限的范围内。
_.clamp(-10, -5, 5); // => -5
_.clamp(10, -5, 5); // =>5
- _.inRange(number, [start=0], end)
- 检查 n 是否介于 start 和 end(不包括 end)之间。
- 如果未指定 end,则将 end 设置为 start 的值,然后将 start 设置为 0。
- 如果 start 大于 end,则交换参数以支持负范围。
_.inRange(3, 2, 4); // => true
_.inRange(4, 8); // => true
_.inRange(4, 2); // => false
_.inRange(2, 2); // => false
_.inRange(1.2, 2); // => true
_.inRange(5.2, 4); // => false
_.inRange(-3, -2, -6); // => true
- _.random([lower=0], [upper=1], [floating])
- 生成一个介于包括下限和上限之间的随机数。
- 如果只提供一个参数,则返回 0 到给定数字之间的数。
- 如果 floating 为 true,或者下限或上限中有一个是浮点数,则返回一个浮点数而不是整数。
_.random(0, 5); // => an integer between 0 and 5
_.random(5); // => also an integer between 0 and 5
_.random(5, true); // => a floating-point number between 0 and 5
_.random(1.2, 5.2); // => a floating-point number between 1.2 and 5.2
- _.ceil(number, [precision=0])
- 计算向上舍入到指定精度的数字。
_.ceil(4.006); // => 5
_.ceil(6.004, 2); // => 6.01
_.ceil(6040, -2); // => 6100
- _.floor(number, [precision=0])
- 计算向下舍入到指定精度的数字。
_.floor(4.006); // => 4
_.floor(0.046, 2); // => 0.04
_.floor(4060, -2); // => 4000
- _.round(number, [precision=0])
- 计算四舍五入到指定精度的数字。
_.round(4.006); // => 4
_.round(4.006, 2); // => 4.01
_.round(4060, -2); // => 4100
- _.max(array)
- 计算数组的最大值。如果数组为空或为假值,则返回 undefined。
_.max([4, 2, 8, 6]); // => 8
_.max([]); // => undefined
- .maxBy(array, [iteratee=.identity])
- 这个方法类似于 _.max,不同之处在于它接受 iteratee,iteratee 会为数组中的每个元素调用,以生成用于对值进行排序的标准。iteratee 会被传入一个参数:(值)。
var objects = [{ 'n': 1 }, { 'n': 2 }];
_.maxBy(objects, function(o) { return o.n; }); // => { 'n': 2 }
// The `_.property` iteratee shorthand.
_.maxBy(objects, 'n'); // => { 'n': 2 }
- _.min(array)
- 计算数组的最小值。如果数组为空或为假值,则返回未定义。
_.min([4, 2, 8, 6]); // => 2
_.min([]); // => undefined
- .minBy(array, [iteratee=.identity])
- 此方法类似于 _.min,不同之处在于它接受 iteratee,该 iteratee 会为数组中的每个元素调用,以生成用于对值进行排序的标准。iteratee 会使用一个参数调用:(value)。
var objects = [{ 'n': 1 }, { 'n': 2 }];
_.minBy(objects, function(o) { return o.n; }); // => { 'n': 1 }
// The `_.property` iteratee shorthand.
_.minBy(objects, 'n'); // => { 'n': 1 }
字符串处理
- _.camelCase([string=''])
- 将字符串转换为驼峰式大小写。
_.camelCase('Foo Bar'); // => 'fooBar'
_.camelCase('--foo-bar--'); // => 'fooBar'
_.camelCase('__FOO_BAR__'); // => 'fooBar'
- _.kebabCase([string=''])
- 将字符串转换为短横线命名法。
_.kebabCase('Foo Bar'); // => 'foo-bar'
_.kebabCase('fooBar'); // => 'foo-bar'
_.kebabCase('__FOO_BAR__'); // => 'foo-bar'
- _.snakeCase([string=''])
- 将字符串转换为蛇形命名法。
_.snakeCase('Foo Bar'); // => 'foo_bar'
_.snakeCase('fooBar'); // => 'foo_bar'
_.snakeCase('--FOO-BAR--'); // => 'foo_bar'
- _.startCase([string=''])
- 将字符串转换为首字母大写的格式。
_.startCase('--foo-bar--'); // => 'Foo Bar'
_.startCase('fooBar'); // => 'Foo Bar'
_.startCase('__FOO_BAR__'); // => 'FOO BAR'
- _.capitalize([string=''])
- 将字符串的第一个字符转换为大写,其余字符转换为小写。
_.capitalize('FRED');
// => 'Fred'
- _.startsWith([string=''], [target], [position=0])
- 检查字符串是否以给定的目标字符串开头。
_.startsWith('abc', 'a'); // => true
_.startsWith('abc', 'b'); // => false
_.startsWith('abc', 'b', 1); // => true
- _.endsWith([string=''], [target], [position=string.length])
- 检查字符串是否以给定的目标字符串结尾。
_.endsWith('abc', 'c'); // => true
_.endsWith('abc', 'b'); // => false
_.endsWith('abc', 'b', 2); // => true
- _.escape([string=''])
- 将字符串中的字符 “&”、“<”、“>”、“"” 和 “'” 转换为相应的 HTML 实体。
_.escape('fred, barney, & pebbles');
// => 'fred, barney, & pebbles'
- _.unescape([string=''])
- _.escape 的反向操作;此方法将字符串中的 HTML 实体 &、<、>、" 和 ' 转换为相应的字符。
_.unescape('fred, barney, & pebbles');
// => 'fred, barney, & pebbles'
- _.escapeRegExp([string=''])
- 转义字符串中的正则表达式特殊字符 “^”、“$”、“\”、“.”、“*”、“+”、“?”、“(”、“)”、“[”、“]”、“{”、“}” 和 “|”。
_.escapeRegExp('[lodash](https://lodash.com/)');
// => '\[lodash\]\(https://lodash\.com/\)'
- _.lowerCase([string=''])
- 将以空格分隔的单词组成的字符串转换为小写形式。
_.lowerCase('--Foo-Bar--'); // => 'foo bar'
_.lowerCase('fooBar'); // => 'foo bar'
_.lowerCase('__FOO_BAR__'); // => 'foo bar'
- _.upperCase([string=''])
- 将以空格分隔的单词组成的字符串转换为大写形式。
_.upperCase('--foo-bar'); // => 'FOO BAR'
_.upperCase('fooBar'); // => 'FOO BAR'
_.upperCase('__foo_bar__'); // => 'FOO BAR'
- _.lowerFirst([string=''])
- 将字符串的第一个字符转换为小写。
_.lowerFirst('Fred'); // => 'fred'
_.lowerFirst('FRED'); // => 'fRED'
- _.upperFirst([string=''])
- 将字符串的第一个字符转换为大写。
_.upperFirst('fred'); // => 'Fred'
_.upperFirst('FRED'); // => 'FRED'
- _.pad([string=''], [length=0], [chars=' '])
- 如果字符串的长度小于指定长度,则在字符串的左右两侧进行填充。如果填充字符的数量不能被指定长度整除,则截断填充字符。
- 右侧填充: _.padEnd([string=''], [length=0], [chars=' '])
- 左侧填充: _.padStart([string=''], [length=0], [chars=' '])
_.pad('abc', 8); // => ' abc '
_.pad('abc', 8, '_-'); // => '_-abc_-_'
_.pad('abc', 3); // => 'abc'
_.padEnd('abc', 6); // => 'abc '
_.padEnd('abc', 6, '_-'); // => 'abc_-_'
_.padEnd('abc', 3); // => 'abc'
_.padStart('abc', 6); // => ' abc'
_.padStart('abc', 6, '_-'); // => '_-_abc'
_.padStart('abc', 3); // => 'abc'
- _.toLower([string=''])
- 将整个字符串转换为小写形式,就像 String#toLowerCase 方法那样。
_.toLower('--Foo-Bar--'); // => '--foo-bar--'
_.toLower('fooBar'); // => 'foobar'
_.toLower('__FOO_BAR__'); // => '__foo_bar__'
- _.toUpper([string=''])
- 将整个字符串转换为大写形式,就像 String#toUpperCase 一样。
_.toUpper('--foo-bar--'); // => '--FOO-BAR--'
_.toUpper('fooBar'); // => 'FOOBAR'
_.toUpper('__foo_bar__'); // => '__FOO_BAR__'
- _.repeat([string=''], [n=1])
- 将给定的字符串重复 n 次。
_.repeat('*', 3); // => '***'
_.repeat('abc', 2); // => 'abcabc'
_.repeat('abc', 0); // => ''
- _.trim([string=''], [chars=whitespace])
- 移除字符串开头和结尾的空白字符或指定字符。
- 删除字符串末尾的空白字符或指定字符: _.trimEnd([string=''], [chars=whitespace])
- 删除字符串开头的空白字符或指定字符: _.trimStart([string=''], [chars=whitespace])
_.trim(' abc '); // => 'abc'
_.trim('-_-abc-_-', '_-'); // => 'abc'
_.map([' foo ', ' bar '], _.trim); // => ['foo', 'bar']
_.trimEnd(' abc '); // => ' abc'
_.trimEnd('-_-abc-_-', '_-'); // => '-_-abc'
_.trimStart(' abc '); // => 'abc '
_.trimStart('-_-abc-_-', '_-'); // => 'abc-_-'
- _.words([string=''], [pattern])
- 将字符串拆分为其单词组成的数组。
_.words('fred, barney, & pebbles');
// => ['fred', 'barney', 'pebbles']
_.words('fred, barney, & pebbles', /[^, ]+/g);
// => ['fred', 'barney', '&', 'pebbles']
- _.truncate([string=''], [options={}])
- 如果字符串长度超过给定的最大字符串长度,则截断该字符串。截断后的字符串的最后几个字符将替换为省略字符串,默认情况下为 “...”。
- [options.length=30] (number): 字符串最大长度.
- [options.omission='...'] (string): 表示文本的字符串被省略.
- [options.separator] (RegExp|string): 要截断到的分隔符模式.
_.truncate('hi-diddly-ho there, neighborino');
// => 'hi-diddly-ho there, neighbo...'
_.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 [...]'
- _.template([string=''], [options={}])
- 创建一个已编译的模板函数,该函数可以在 “interpolate” 定界符中插入数据属性,在 “escape” 定界符中对插入的数据属性进行 HTML 转义,并在 “evaluate” 定界符中执行 JavaScript。
- 在模板中,数据属性可以作为自由变量进行访问。如果提供了一个设置对象,它将优先于 _.templateSettings 值。
- [options.escape=_.templateSettings.escape] (RegExp): HTML “转义” 定界符。.
- [options.evaluate=_.templateSettings.evaluate] (RegExp): "evaluate" 定界符.
- [options.imports=_.templateSettings.imports] (Object): 要作为自由变量导入到模板中的对象
- [options.interpolate=_.templateSettings.interpolate] (RegExp): “插值” 分隔符。
- [options.sourceURL='lodash.templateSources[n]'] (string): 已编译模板的源 URL。
- [options.variable='obj'] (string): 数据对象变量名
// Use the "interpolate" delimiter to create a compiled template.
var compiled = _.template('hello <%= user %>!');
compiled({ 'user': 'fred' });
// => 'hello fred!'
// Use the HTML "escape" delimiter to escape data property values.
var compiled = _.template('<b><%- value %></b>');
compiled({ 'value': '<script>' });
// => '<b><script></b>'
// Use the "evaluate" delimiter to execute JavaScript and generate HTML.
var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>');
compiled({ 'users': ['fred', 'barney'] });
// => '<li>fred</li><li>barney</li>'
// Use the internal `print` function in "evaluate" delimiters.
var compiled = _.template('<% print("hello " + user); %>!');
compiled({ 'user': 'barney' });
// => 'hello barney!'
// Use the ES template literal delimiter as an "interpolate" delimiter.
// Disable support by replacing the "interpolate" delimiter.
var compiled = _.template('hello ${ user }!');
compiled({ 'user': 'pebbles' });
// => 'hello pebbles!'
// Use backslashes to treat delimiters as plain text.
var compiled = _.template('<%= "\\<%- value %\\>" %>');
compiled({ 'value': 'ignored' });
// => '<%- value %>'
// Use the `imports` option to import `jQuery` as `jq`.
var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>';
var compiled = _.template(text, { 'imports': { 'jq': jQuery } });
compiled({ 'users': ['fred', 'barney'] });
// => '<li>fred</li><li>barney</li>
// Use the `sourceURL` option to specify a custom sourceURL for the template.
var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' });
compiled(data);
// => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector.
// Use the `variable` option to ensure a with-statement isn't used in the compiled template.
var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' });
compiled.source;
// => function(data) {
// var __t, __p = '';
// __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!';
// return __p;
// }
// Use custom template delimiters.
_.templateSettings.interpolate = /{{([\s\S]+?)}}/g;
var compiled = _.template('hello {{ user }}!');
compiled({ 'user': 'mustache' });
// => 'hello mustache!'
// Use the `source` property to inline compiled templates for meaningful
// line numbers in error messages and stack traces.
fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\
var JST = {\
"main": ' + _.template(mainText).source + '\
};\
');