lodash学习笔记
lodash 详解
介绍
Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库。Lodash 遵循 MIT 开源协议发布,并且支持最新的运行环境。
Lodash 通过降低 array、number、objects、string 等等的使用难度从而让 JavaScript 变得更简单。 Lodash 的模块化方法 非常适用于:
- 遍历 array、object 和 string
- 对值进行操作和检测
- 创建符合功能的函数
对于源码中的主要关键部分,我将使用注释进行解释,或者单独使用一节进行解析
阅读此篇,最好:
- 熟悉ES6规范
- 熟悉JS原生对象与函数
- 了解迭代器
- 熟悉JS闭包
- 一定的算法基础
迭代器简写
注意:这里说的迭代器仅限于lodash中的迭代器,而非JavaScript迭代器。因为lodash中的迭代器有时并非以函数形式作为参数,所以我称它为迭代器而非迭代函数,除此之外,lodash中的predicate断言函数也常常在迭代遍历中调用(或者说predicate也是一种迭代器,只不过相比寻常迭代器,predicate只返回布尔值,并且会打断循环),因此lodash中的predicate断言也可以进行简写
iteratee shorthand
lodash里有些函数支持迭代器简写,有些不支持,那什么是迭代器简写呢?
iteratee 迭代器,常用于数组类与集合类方法中,传入一个值到迭代器中,会返回一个新的值,因此它的返回可以是任意的
如果传入的迭代器的类型直接就是一个函数,如
function(o) { return o.age < 40; }
这种形式的,那它就是一个全写
而如果传入的是
{'active': false }
或者
['active', false]
亦或者
'active'
那么这就叫简写
举个例子
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': 40 })
_.find(users, ['age': 40 ])
这三个find是等效的,都会返回数组中第二个对象
{ user: 'fred', age: 40, active: false }
而下面这个
_.find(users, 'active')
则会返回第一个Boolean(active)为真的对象,也就是下面这个
{ user: 'barney', age: 36, active: true }
至于为什么能够使用简写,是因为支持简写的方法使用了baseIteratee函数将这些简写转成了一个完整的方法,而关于baseIteratee是如何通过简写来生成一个完整迭代器的可以查看baseIteratee
SameValueZero
SameValueZero 是ES6中的比较算法或者说比较规范之一,lodash中有部分函数使用了SameValueZero 进行相等比较,它与SameValue的主要区别在于在SameValueZero 中,+0和-0是相等的。
SameValueZero(x, y)
The internal comparison abstract operation SameValueZero(x, y), where x and y are ECMAScript language values, produces true or false. Such a comparison is performed as follows:
ReturnIfAbrupt(x).
ReturnIfAbrupt(y).
If Type(x) is different from Type(y), return false.
If Type(x) is Undefined, return true.
If Type(x) is Null, return true.
If Type(x) is Number, then
If x is NaN and y is NaN, return true.
If x is +0 and y is −0, return true.
If x is −0 and y is +0, return true.
If x is the same Number value as y, return true.
Return false.
If Type(x) is String, then
If x and y are exactly the same sequence of code units (same length and same code units at corresponding indices) return true; otherwise, return false.
If Type(x) is Boolean, then
If x and y are both true or both false, return true; otherwise, return false.
If Type(x) is Symbol, then
If x and y are both the same Symbol value, return true; otherwise, return false.
Return true if x and y are the same Object value. Otherwise, return false.NOTE SameValueZero differs from SameValue only in its treatment of +0 and −0.
- 如果 x 和 y 的类型不同,返回 false
- 如果 x 的类型为 Undefined ,返回 true
- 如果 x 的类型为 Null ,返回 true
- 如果 x 的类型为 Number
- 如果 x 为 NaN 并且 y 为 NaN ,返回 true
- 如果 x 为 +0 并且 y 为 -0 ,返回 true
- 如果 x 为 -0 并且 y 为 +0 , 返回 true
- 如果 x 和 y 的数值一致,返回 true
- 否则返回false
- 如果 x 的类型为 String,并且 x 和 y 的长度及编码相同,返回 true,否则返回 false
- 如果 x 的类型为 Boolean ,并且 x 和 y 同为 true 或同为false ,返回 true,否则返回 false
- 如果 x 的类型为 Symbol ,并且 x 和 y 具有相同的 Symbol 值,返回 true,否则返回 false
- 如果 x 和 y 指向同一个对象,返回 true, 否则返回 false
predicate,iteratee与comparator
如果有一定观察,会发现很多lodash函数都接收有一个特别的参数,叫做predicate或者iteratee亦或者comparator,当然,也有可能具有其中的多个。
lodash的工具方法中常常会接收一个函数作为参数,即使不是函数,也可以通过一定的方法转化为函数,比如迭代器简写
lodash容许使用者通过传递predicate,iteratee与comparator,对工具函数的内部逻辑进行一定的影响,通过字面意思我们就可以知道这三个参数名代表着什么参数
- predicate 断言函数,它的返回是布尔值,可以阻止循环,直接返回结果,获取满足条件的一个或一组值,也可以继续循环,获取满足条件的所有值,一般接收三个参数,当前值value,当前索引index,数组array
- iteratee 迭代器,常用于数组类与集合类方法中,传入一个值到迭代器中,会返回一个新的值,因此它的返回可以是任意的
- comparator 比较器,比较器有点类似于上面的断言函数,它不会阻断循环。比较器也返回布尔值,与断言不同的是,比较器主要用于对两个数组中值进行比较,一般接收两个参数,value当前主数组的待比较值,other辅助数组(条件数组)的被比较值。
symmetric difference
symmetric difference,数学术语:对等差分
具体描述参见 https://en.wikipedia.org/wiki/Symmetric_difference
给出两个集合 (如集合 A = {1, 2, 3} 和集合 B = {2, 3, 4}), 而数学术语 “对等差分”的集合就是指由所有只在两个集合其中之一的元素组成的集合(A △ B = C = {1, 4}).
对于传入的额外集合 (如 D = {2,3,5}), 应该按前面原则求前两个集合的结果与新集合的对等差分集合 (C △ D = {1, 4} △ {2, 3, 5} = {1, 2, 3, 4, 5})
类数组,类对象,类数组对象
类数组
如果value是一个类数组
- value不为null或undefined。
- typeOf value !== ‘function’
- typeOf value.length===‘number’&&value.length % 1===0
类对象
如果value是一个类对象
- value不为null或undefined
- typeof value 返回值为 object
function、array和object都算类对象
类数组对象
类数组对象在类数组的基础上添加一个条件:value必须为类对象。
受保护的方法
lodash 中有许多方法是防止作为其他方法的迭代函数(注:即不能作为iteratee参数传递给其他方法),例如:.every,.filter,.map,.mapValues,_.reject, 和some。
受保护的方法有(注:即这些方法不能使用_.every,.filter,.map,.mapValues,.reject, 和_.some作为 iteratee 迭代函数参数) :
ary
, chunk
, curry
, curryRight
, drop
, dropRight
, every
,fill
, invert
, parseInt
, random
, range
, rangeRight
, repeat
,sampleSize
, slice
, some
, sortBy
, split
, take
, takeRight
,template
, trim
, trimEnd
, trimStart
, and words
位掩码bitmask
位掩码可以在lodash的很多工具方法的基础实现中找到,大多以参数形式出现,这是lodash内部定义的一个具有复合含义的值,在代码中虽然以十进制书写,但其实际意义主要由其而二进制位表示,并且其在代码中主要用到的也是位运算。
从第一位到第十位的表示意义依次如下:
-
WRAP_BIND_FLAG 十进制值 1,二进制表示 0000000001,表示bind函数的标识。典型函数:bind,bindKey
-
WRAP_BIND_KEY_FLAG 十进制 2,二进制表示 0000000010,表示bindKey函数的标识。典型函数:bindKey
-
4
-
WRAP_CURRY_FLAG 十进制 8,二进制表示 0000001000,表示柯里化标识。典型函数:curry
-
WRAP_CURRY_RIGHT_FLAG 十进制16,二进制表示 0000010000,表示柯里化标识。典型函数:curryRight
-
WRAP_PARTIAL_FLAG 十进制 32,二进制表示 0000100000,表示是否应用部分参数(函数包装时传递的参数,为了参数复用,即预设参数)。典型函数:bind,bindKey,partial
-
WRAP_PARTIAL_RIGHT_FLAG 十进制64 ,二进制表示0001000000 表示 附加到提供给新函数的参数后面的参数(占位符参数,从右开始的预设参数)。典型函数:partialRight
-
WRAP_ARY_FLAG 十进制 128,二进制表示0010000000,表示ary函数的标识。典型函数:ary
-
WRAP_REARG_FLAG十进制 256,二进制表示0100000000,表示rearg函数的标识。典型函数:rearg
-
WRAP_FLIP_FLAG 十进制 512,二进制表示1000000000,表示参数翻转的标识。典型函数:flip
bind与bindKey的区别
bindKey中返回的闭包获取对象函数是这样的
bind获取的是func,func是函数包装时传入的函数引用,修改原函数无影响(实质上是创建了新函数,原来的函数依旧存在,并且正被bind使用中)。
function bind(func: Function) {
return function () {
func()
}
}
let funcA = () => console.log('funcA');
let fA = bind(funcA);
fA()//funcA
funcA = () => console.log('change funcA');//funcA存放的函数引用被修改为新函数,但是func引用无变化
fA()//funcA
bindKey获取的是对象内部函数的引用,函数包装时传递的是对象(引用),修改对象中的函数,其存放的函数引用发生变化,fn也就发生变化。
function bindKey(key: string, obj: any) {
return function () {
obj[key]();
}
}
let objA = {
funcA: () => console.log('funcA'),
}
let fA = bindKey('funcA', objA);
fA()//funcA
objA.funcA = () => console.log('change funcA');//objA.funcA存放的函数引用被修改为新函数,但是objA的引用未变化
fA()//change funcA
分类
数组
序号 | 函数名 | 描述 |
---|---|---|
1 | chunk | 数组拆分重组 |
2 | compact | 数组假值过滤 |
3 | concat | 数组连接 |
4 | difference | 数组指定过滤 |
5 | differenceBy | 数组迭代过滤 |
6 | differenceWith | 数组条件过滤 |
7 | drop | 去除数组前n个元素 |
8 | [dropRight ](# dropRight去除数组后n个元素) | 去除数组后n个元素 |
9 | dropRightWhile | 数组尾部条件过滤 |
10 | fill | 数组填充 |
11 | findIndex | 数组查询 |
12 | findLastIndex | 数组倒序查询 |
13 | flatten | 数组一级展开 |
14 | flattenDeep | 数组完全扁平化 |
15 | flattenDepth | 数组指定层级展开 |
16 | fromPairs | 数组转对象 |
17 | head | 获取数组第一个元素 |
18 | indexOf | 数组查询 |
19 | initial | 获取数组前length-2项 |
20 | intersection | 数组交集 |
21 | intersectionBy | 数组迭代处理交集 |
22 | intersectionWith | 数组自定义交集 |
23 | join | 数组以指定分隔符转为字符串 |
24 | last | 获取数组最后一个元素 |
25 | lastIndexOf | 数组倒序查询 |
26 | nth | 数组获取指定索引元素 |
27 | pull | 数组移除指定值 |
28 | pullAll | 数组移除指定列表中的值 |
29 | pullAllBy | 数组迭代移除 |
30 | pullAllWith | 数组条件移除 |
31 | pullAt | 数组移除对应索引元素 |
32 | remove | 数组条件移除所有值 |
33 | reverse | 数组倒置 |
34 | slice | 数组截取 |
35 | sortedIndex | 有序数组最小插入索引 |
36 | sortedIndexBy | 有序数组迭代最小插入索引 |
37 | sortedIndexOf | 有序数组二分查找 |
38 | sortedLastIndex | 有序数组最大插入索引 |
39 | sortedLastIndexBy | 有序数组迭代最大插入索引 |
40 | sortedLastIndexOf | 有序数组倒序二分查找 |
41 | sortedUniq | 有序数组去重 |
42 | sortedUniqBy | 有序数组迭代去重 |
43 | tail | 获取数组后length-2项 |
44 | take | 数组提取 |
45 | takeRight | 数组倒序提取 |
46 | takeRightWhile | 数组倒序断言提取 |
47 | takeWhile | 数组断言提取 |
48 | union | 数组并集去重 |
49 | unionBy | 数组并集迭代去重 |
50 | unionWith | 数组并集比较去重 |
51 | uniq | 数组去重 |
52 | uniqBy | 数组迭代去重 |
53 | uniqWith | 数组比较去重 |
54 | unZip | 数组解压缩 |
55 | unZipWith | 数组指定分组 |
56 | without | 数组剔除给定值 |
57 | xor | 给定数组唯一值 |
58 | xorBy | 给定数组迭代唯一值 |
59 | xorWith | 给定数组条件唯一值 |
60 | zip | 数组重新分组 |
61 | zipObject | 数组构造对象 |
62 | zipObjectDeep | 数组构造对象支持深度路径 |
63 | zipWith | 数组迭代分组 |
集合
序号 | 函数名 | 描述 |
---|---|---|
1 | countBy | 集合迭代统计 |
2 | every | 集合遍历检查 |
3 | filter | 集合过滤 |
4 | find | 集合查询 |
5 | findLast | 集合倒序查询 |
6 | flatMap | 迭代结果扁平化 |
7 | flatMapDeep | 迭代结果完全扁平化 |
8 | flatMapDepth | 迭代结果指定层级展开 |
9 | forEach | 集合遍历 |
10 | forEachRight | 集合反向遍历 |
11 | groupBy | 集合迭代分组 |
12 | includes | 集合包含查询 |
13 | invokeMap | 集合迭代调用 |
14 | keyBy | 集合迭代生成键 |
15 | map | 集合遍历 |
16 | orderBy | 集合迭代结果指定排序 |
17 | partition | 集合分组 |
18 | reduce | 集合累计操作 |
19 | reduceRight | 集合倒序累计操作 |
20 | reject | 集合filter反向过滤 |
21 | sample | 获取集合中一个随机元素 |
22 | sampleSize | 获取集合中n个随机元素 |
23 | shuffle | 集合随机重组为数组 |
24 | size | 获取集合长度 |
25 | some | 集合元素存在鉴定 |
26 | sortBy | 集合迭代升序 |
对象
序号 | 函数名 | 描述 |
---|---|---|
1 | ||
2 | ||
3 | ||
4 | ||
5 | at | 根据路径获取对象值 |
6 | ||
7 | ||
8 | ||
9 | ||
10 | ||
11 | ||
12 | ||
13 | ||
14 | ||
15 | ||
16 | ||
17 | ||
18 | ||
19 | ||
20 | ||
21 | ||
22 | ||
23 | keys | 对象属性名数组 |
24 | ||
25 | ||
26 | ||
27 | ||
28 | ||
29 | ||
30 | ||
31 | ||
32 | ||
33 | ||
34 | ||
35 | ||
36 | ||
37 | ||
38 | ||
39 | ||
40 | ||
41 | ||
42 | values | 对象值数组 |
43 |
函数
序号 | 函数名 | 描述 |
---|---|---|
1 | after | 定次触发 |
2 | ary | 参数次数限制 |
3 | before | 限次触发 |
4 | bind | 函数指定this |
5 | bindKey | 对象中函数指定this |
6 | curry | 函数柯里化 |
7 | curryRight | 函数柯里化倒序接收附加参数 |
8 | debounce | 函数防抖 |
9 | defer | 函数推迟调用 |
10 | delay | 函数延迟调用 |
11 | flip | 函数参数翻转 |
12 | ||
13 | negate | 创建取反函数 |
14 | once | 函数单次调用 |
15 | overArgs | 函数参数覆写 |
16 | partial预设参数 | 预设参数 |
17 | partialRight附加预设参数 | 附加预设参数 |
18 | rearg函数指定参数调用 | 函数指定参数调用 |
19 | ||
20 | ||
21 | throttle | 函数节流 |
22 | ||
23 |
数学
序号 | 函数名 | 描述 |
---|---|---|
1 | add | 加法 |
2 | ceil | 向上舍入 |
3 | divide | 两数相除 |
4 | floor | 向下舍入 |
5 | ||
6 | ||
7 | maen | 数组均值计算 |
8 | ||
9 | ||
10 | ||
11 | multiply | 两数相乘 |
12 | round | 四舍五入 |
13 | subtract | 两数相减 |
14 | ||
15 |
数字
序号 | 函数名 | 描述 |
---|---|---|
1 | ||
2 | ||
3 |
语言
序号 | 函数名 | 描述 |
---|---|---|
1 | castArray | 转换为数组 |
2 | ||
3 | ||
4 | ||
5 | ||
6 | ||
7 | eq | 值比较 |
8 | ||
9 | ||
10 | ||
11 | isArray | 检查数组 |
12 | ||
13 | isArrayLike | 检查类数组 |
14 | isArrayLikeObject | 检查类数组对象 |
15 | ||
16 | ||
17 | ||
18 | ||
19 | ||
20 | ||
21 | ||
22 | isError | 检查异常 |
23 | ||
24 | isFunction | 检查函数 |
25 | ||
26 | isLength | 检查有效长度 |
27 | ||
28 | ||
29 | ||
30 | isNaN | 检查NaN |
31 | ||
32 | isNil | 检查null或者undefined |
33 | isNull | 检查null |
34 | isNumber | 检查number |
35 | isObject | 检查对象 |
36 | isObjectLike | 检查类对象 |
37 | isPlainObject | 检查普通对象 |
38 | ||
39 | ||
40 | ||
41 | isString | 检查字符串 |
42 | isSymbol | 检查符号 |
43 | ||
44 | ||
45 | ||
46 | ||
47 | ||
48 | ||
49 | ||
50 | toFinite | 转为有限数字 |
51 | toInteger | 转为整数 |
52 | ||
53 | toNumber | 转为数字 |
54 | ||
55 | ||
56 | toString | 转为字符串 |
Seq
序号 | 函数名 | 描述 |
---|---|---|
字符串
序号 | 函数名 | 描述 |
---|---|---|
1 | ||
2 | ||
3 | deburr | 转换基本拉丁字母 |
4 | ||
5 | ||
6 | ||
7 | ||
8 | ||
9 | ||
10 | ||
11 | ||
12 | ||
13 | ||
14 | ||
15 | ||
16 | ||
17 | ||
18 | ||
19 | ||
20 | ||
21 | toLower | 字符串转小写 |
22 | toUpper | 字符串转大写 |
23 | ||
24 | ||
25 | ||
26 | ||
27 | ||
28 | ||
29 | ||
30 |
实用函数
序号 | 函数名 | 描述 |
---|---|---|
1 | attempt | 函数尝试调用 |
2 | ||
3 | ||
4 | ||
5 | constant | 返回value |
6 | ||
7 | ||
8 | ||
9 | identity | 返回首个提供的参数 |
10 | ||
11 | ||
12 | ||
13 | ||
14 | ||
15 | ||
16 | ||
17 | ||
18 | ||
19 | ||
20 | ||
21 | ||
22 | ||
23 | ||
24 | ||
25 | ||
26 | ||
27 | ||
28 | ||
29 | ||
30 | ||
31 | ||
32 | ||
33 | ||
34 |
Properties
序号 | 函数名 | 描述 |
---|---|---|
1 | ||
2 | ||
3 | ||
4 | ||
5 | ||
6 | ||
7 |
Methods
序号 | 函数名 | 描述 |
---|---|---|
1 |
Date
序号 | 函数名 | 描述 |
---|---|---|
1 | now | 获取Unix纪元至今毫秒数 |
add加法
add(augend, addend)
Adds two numbers.
两个数相加。
参数
- augend number 被加数
- addend number 加数
返回
number
计算后的值
源码
源码中涉及的函数
var createMathOperation = require('./_createMathOperation');
/**
* Adds two numbers.
*
* @static
* @memberOf _
* @since 3.4.0
* @category Math
* @param {number} augend The first number in an addition.
* @param {number} addend The second number in an addition.
* @returns {number} Returns the total.
* @example
*
* _.add(6, 4);
* // => 10
*/
var add = createMathOperation(function(augend, addend) {
return augend + addend;
}, 0);
module.exports = add;
after定次触发
after(n, func)
The opposite of
_.before
; this method creates a function that invokesfunc
once it’s calledn
or more times._.before的反向函数;此方法创建一个函数,当他被调用
n
或更多次之后将马上触发func
。
参数
n
(number):func
方法应该在调用多少次后才执行。func
(Function): 用来限定的函数。
返回
(Function): 返回新的限定函数。
示例
示例1
var saves = ['profile', 'settings'];
var done = after(saves.length, function () {
console.log('done saving!');
});
forEach(saves, function (type) {
console.log('type', type)
done()
});
输出
type profile
type settings
done saving!
当第二次触发done的时候,才执行done
源码
源码中涉及的方法
var toInteger = require('./toInteger');
/** Error message constants. */
var FUNC_ERROR_TEXT = 'Expected a function';
/**
* The opposite of `_.before`; this method creates a function that invokes
* `func` once it's called `n` or more times.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Function
* @param {number} n The number of calls before `func` is invoked.
* @param {Function} func The function to restrict.
* @returns {Function} Returns the new restricted function.
* @example
*
* var saves = ['profile', 'settings'];
*
* var done = _.after(saves.length, function() {
* console.log('done saving!');
* });
*
* _.forEach(saves, function(type) {
* asyncSave({ 'type': type, 'complete': done });
* });
* // => Logs 'done saving!' after the two async saves have completed.
*/
function after(n, func) {
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
n = toInteger(n);
//这里用到了闭包,匿名函数引用了after中的变量n
return function() {
if (--n < 1) {
return func.apply(this, arguments);
}
};
}
module.exports = after;
ary参数次数限制
ary(func,[n],[fuard])
Creates a function that invokes
func
, with up ton
arguments, ignoring any additional arguments.创建一个调用func的函数。调用func时最多接受 n个参数,忽略多出的参数。
参数
- func 需要被限制参数个数的函数。
- n 可选 限制的参数数量。
- guard 可选 允许像’ _.map '这样的方法使用作为迭代对象。true/false
返回
function
被限制参数数量后的方法
用例1
let a = ['6', '5', '4']
console.log(a.map(parseInt))//[ 6, NaN, NaN ]
console.log(a.map(ary(parseInt), 1))//[ 6, 5, 4 ]
用例2
let b = ary(console.log, 1)
console.log(b(1, 2, 3))
//1
//undefined
源码
源码中涉及的方法
源码中涉及的常量
var createWrap = require('./_createWrap');
/** Used to compose bitmasks for function metadata. */
var WRAP_ARY_FLAG = 128;
/**
* Creates a function that invokes `func`, with up to `n` arguments,
* ignoring any additional arguments.
*
* @static
* @memberOf _
* @since 3.0.0
* @category Function
* @param {Function} func The function to cap arguments for.
* @param {number} [n=func.length] The arity cap.
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
* @returns {Function} Returns the new capped function.
* @example
*
* _.map(['6', '8', '10'], _.ary(parseInt, 1));
* // => [6, 8, 10]
*/
function ary(func, n, guard) {
n = guard ? undefined : n;
n = (func && n == null) ? func.length : n;//如果没传n,默认参数数量func的参数个数
return createWrap(func, WRAP_ARY_FLAG, undefined, undefined, undefined, undefined, n);
}
module.exports = ary;
at根据路径获取对象值
at(object, [paths])
Creates an array of values corresponding to
paths
ofobject
.创建一个数组,值来自 object 的paths路径相应的值。
参数
- object Object 要获取值的对象
- paths Array 路径数组,支持深层路径a.b或者a[0].b等
返回
Array
返回选中值的数组。
源码
源码中涉及的函数
var baseAt = require('./_baseAt'),
flatRest = require('./_flatRest');
/**
* Creates an array of values corresponding to `paths` of `object`.
*
* @static
* @memberOf _
* @since 1.0.0
* @category Object
* @param {Object} object The object to iterate over.
* @param {...(string|string[])} [paths] The property paths to pick.
* @returns {Array} Returns the picked values.
* @example
*
* var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
*
* _.at(object, ['a[0].b.c', 'a[1]']);
* // => [3, 4]
*/
var at = flatRest(baseAt);
module.exports = at;
attempt函数尝试调用
attempt(func, [args])
Attempts to invoke
func
, returning either the result or the caught error object. Any additional arguments are provided tofunc
when it’s invoked.尝试调用func,返回结果 或者 捕捉错误对象。任何附加的参数都会在调用时传给func。
参数
- func Function 尝试调用的函数
- args …any 可选 rest 传递给func的参数
返回
any
返回函数func的调用结果或者捕捉的异常对象
源码
源码中涉及的函数
var apply = require('./_apply'),
baseRest = require('./_baseRest'),
isError = require('./isError');
/**
* Attempts to invoke `func`, returning either the result or the caught error
* object. Any additional arguments are provided to `func` when it's invoked.
*
* @static
* @memberOf _
* @since 3.0.0
* @category Util
* @param {Function} func The function to attempt.
* @param {...*} [args] The arguments to invoke `func` with.
* @returns {*} Returns the `func` result or error object.
* @example
*
* // Avoid throwing errors for invalid selectors.
* var elements = _.attempt(function(selector) {
* return document.querySelectorAll(selector);
* }, '>_>');
*
* if (_.isError(elements)) {
* elements = [];
* }
*/
var attempt = baseRest(function(func, args) {
try {
return apply(func, undefined, args);
} catch (e) {
return isError(e) ? e : new Error(e);
}
});
module.exports = attempt;
before限次触发
before(n, func)
Creates a function that invokes
func
, with thethis
binding and arguments of the created function, while it’s called less thann
times. Subsequent calls to the created function return the result of the lastfunc
invocation.创建一个调用func的函数,通过this绑定和创建函数的参数调用func,调用次数不超过 n 次。 之后再调用这个函数,将返回一次最后调用func的结果。
参数
- n number 超过多少次不再调用func(注:限制调用func 的次数)
- func Function 限制执行的函数。最多调用n-1次
返回
Function
返回新的限定函数。
示例
示例1
let a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
let newConsole = before(5, console.log)
a.forEach(i => newConsole(i))
//1
//2
//3
//4
示例2
之后再调用这个函数,将返回一次最后调用func的结果。
let newConsole = before(5, function (n) {
console.log(`第${n}次调用`)
return n
})
let res = []
res.push(newConsole(1))
res.push(newConsole(2))
res.push(newConsole(3))
res.push(newConsole(4))
res.push(newConsole(5))
res.push(newConsole(6))
res.push(newConsole(7))
console.log('res ', res)
// 第1次调用
// 第2次调用
// 第3次调用
// 第4次调用
// res [1, 2, 3, 4, 4, 4, 4]
解析
var toInteger = require('./toInteger');
/** Error message constants. */
var FUNC_ERROR_TEXT = 'Expected a function';
/**
* Creates a function that invokes `func`, with the `this` binding and arguments
* of the created function, while it's called less than `n` times. Subsequent
* calls to the created function return the result of the last `func` invocation.
*
* @static
* @memberOf _
* @since 3.0.0
* @category Function
* @param {number} n The number of calls at which `func` is no longer invoked.
* @param {Function} func The function to restrict.
* @returns {Function} Returns the new restricted function.
* @example
*
* jQuery(element).on('click', _.before(5, addContactToList));
* // => Allows adding up to 4 contacts to the list.
*/
function before(n, func) {
var result;
//如果func不是函数,抛出异常
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
n = toInteger(n);
//返回新的限定函数
return function() {
//如果当前调用次数小于限定次数,执行限定函数并使用result存放结果
if (--n > 0) {
result = func.apply(this, arguments);
}
if (n <= 1) {
func = undefined;
}
//返回最后一次调用的结果
return result;
};
}
module.exports = before;
源码
源码中涉及的函数
var toInteger = require('./toInteger');
/** Error message constants. */
var FUNC_ERROR_TEXT = 'Expected a function';
/**
* Creates a function that invokes `func`, with the `this` binding and arguments
* of the created function, while it's called less than `n` times. Subsequent
* calls to the created function return the result of the last `func` invocation.
*
* @static
* @memberOf _
* @since 3.0.0
* @category Function
* @param {number} n The number of calls at which `func` is no longer invoked.
* @param {Function} func The function to restrict.
* @returns {Function} Returns the new restricted function.
* @example
*
* jQuery(element).on('click', _.before(5, addContactToList));
* // => Allows adding up to 4 contacts to the list.
*/
function before(n, func) {
var result;
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
n = toInteger(n);
return function() {
if (--n > 0) {
result = func.apply(this, arguments);
}
if (n <= 1) {
func = undefined;
}
return result;
};
}
module.exports = before;
bind函数指定this
bind(func, thisArg, [partials])
Creates a function that invokes
func
with thethis
binding ofthisArg
andpartials
prepended to the arguments it receives.The
_.bind.placeholder
value, which defaults to_
in monolithic builds, may be used as a placeholder for partially applied arguments.创建一个调用
func
的函数,thisArg
绑定func
函数中的this
(注:this
的上下文为thisArg
) ,并且func
函数会接收partials
附加参数。
_.bind.placeholder
值,默认是以_
作为附加部分参数的占位符。
注意: 不同于原生的 Function#bind
,这个方法不会设置绑定函数的 “length” 属性。
参数
- func Function 绑定的函数
- thisArg any func绑定的this对象
- partials …any 可选 rest 附加的部分参数
返回
Function
返回新的绑定函数
示例
示例1
这个例子主要说明bind与bindKey的区别,bind返回闭包,保存的函数引用未变更,因此改变原来绑定的greet函数并不会影响bound
var greet = function (greeting, punctuation) {
return greeting + ' ' + this.user + punctuation;
}
var object = { 'user': 'fred' };
var bound = bind(greet, object, 'hi');
console.log(bound('!'));
//hi fred!
greet = function (greeting, punctuation) {
return greeting + 'ya ' + this.user + punctuation;
}
console.log(bound('!'));
//hi fred!
解析
var baseRest = require('./_baseRest'),//rest包装
createWrap = require('./_createWrap'),
getHolder = require('./_getHolder'),//获取占位符
replaceHolders = require('./_replaceHolders');//占位符替换,返回被替换的占位符的索引数组
/** Used to compose bitmasks for function metadata. */
var WRAP_BIND_FLAG = 1,
WRAP_PARTIAL_FLAG = 32;
/**
* Creates a function that invokes `func` with the `this` binding of `thisArg`
* and `partials` prepended to the arguments it receives.
*
* The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
* may be used as a placeholder for partially applied arguments.
*
* **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
* property of bound functions.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Function
* @param {Function} func The function to bind.
* @param {*} thisArg The `this` binding of `func`.
* @param {...*} [partials] The arguments to be partially applied.
* @returns {Function} Returns the new bound function.
* @example
*
* 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!'
*/
var bind = baseRest(function(func, thisArg, partials) {
//初始化位掩码
var bitmask = WRAP_BIND_FLAG;
//如果有附加参数
if (partials.length) {
var holders = replaceHolders(partials, getHolder(bind));
bitmask |= WRAP_PARTIAL_FLAG;//位掩码加上partial的标识 或操作 例 a=2 a|=4 则a此时为6(二进制下110)
}
return createWrap(func, bitmask, thisArg, partials, holders);
});
// Assign default placeholders.
bind.placeholder = {};
module.exports = bind;
源码
源码中涉及到的函数
var baseRest = require('./_baseRest'),
createWrap = require('./_createWrap'),
getHolder = require('./_getHolder'),
replaceHolders = require('./_replaceHolders');
/** Used to compose bitmasks for function metadata. */
var WRAP_BIND_FLAG = 1,
WRAP_PARTIAL_FLAG = 32;
/**
* Creates a function that invokes `func` with the `this` binding of `thisArg`
* and `partials` prepended to the arguments it receives.
*
* The `_.bind.placeholder` value, which defaults to `_` in monolithic builds,
* may be used as a placeholder for partially applied arguments.
*
* **Note:** Unlike native `Function#bind`, this method doesn't set the "length"
* property of bound functions.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Function
* @param {Function} func The function to bind.
* @param {*} thisArg The `this` binding of `func`.
* @param {...*} [partials] The arguments to be partially applied.
* @returns {Function} Returns the new bound function.
* @example
*
* 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!'
*/
var bind = baseRest(function(func, thisArg, partials) {
var bitmask = WRAP_BIND_FLAG;
if (partials.length) {
var holders = replaceHolders(partials, getHolder(bind));
bitmask |= WRAP_PARTIAL_FLAG;
}
return createWrap(func, bitmask, thisArg, partials, holders);
});
// Assign default placeholders.
bind.placeholder = {};
module.exports = bind;
bindKey对象中函数指定this
bindKey(object, key, [partials])
Creates a function that invokes the method at
object[key]
withpartials
prepended to the arguments it receives.This method differs from
_.bind
by allowing bound functions to reference methods that may be redefined or don’t yet exist. See Peter Michaux’s article for more details.The
_.bindKey.placeholder
value, which defaults to_
in monolithic builds, may be used as a placeholder for partially applied arguments.创建一个函数,在
object[key]
上通过接收partials
附加参数,调用这个方法。这个方法与_.bind 的不同之处在于允许重新定义绑定函数即使它还不存在。 浏览Peter Michaux’s article 了解更多详情。
_.bind.placeholder
值,默认是以_
作为附加部分参数的占位符。
参数
- object Object 需要绑定函数的对象。
- key string 需要绑定函数对象的键。
- partials …any 可选 rest 提前传入的参数
返回
Function
返回新的绑定函数
源码
源码中涉及到的函数
var baseRest = require('./_baseRest'),
createWrap = require('./_createWrap'),
getHolder = require('./_getHolder'),
replaceHolders = require('./_replaceHolders');
/** Used to compose bitmasks for function metadata. */
var WRAP_BIND_FLAG = 1,
WRAP_BIND_KEY_FLAG = 2,
WRAP_PARTIAL_FLAG = 32;
/**
* Creates a function that invokes the method at `object[key]` with `partials`
* prepended to the arguments it receives.
*
* This method differs from `_.bind` by allowing bound functions to reference
* methods that may be redefined or don't yet exist. See
* [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern)
* for more details.
*
* The `_.bindKey.placeholder` value, which defaults to `_` in monolithic
* builds, may be used as a placeholder for partially applied arguments.
*
* @static
* @memberOf _
* @since 0.10.0
* @category Function
* @param {Object} object The object to invoke the method on.
* @param {string} key The key of the method.
* @param {...*} [partials] The arguments to be partially applied.
* @returns {Function} Returns the new bound function.
* @example
*
* 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;
* };
*
* bound('!');
* // => 'hiya fred!'
*
* // Bound with placeholders.
* var bound = _.bindKey(object, 'greet', _, '!');
* bound('hi');
* // => 'hiya fred!'
*/
var bindKey = baseRest(function(object, key, partials) {
var bitmask = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG;
if (partials.length) {
var holders = replaceHolders(partials, getHolder(bindKey));
bitmask |= WRAP_PARTIAL_FLAG;
}
return createWrap(key, bitmask, object, partials, holders);
});
// Assign default placeholders.
bindKey.placeholder = {};
module.exports = bindKey;
castArray转换为数组
castArray(value)
Casts
value
as an array if it’s not one.如果
value
不是数组, 那么强制转为数组。
参数
- value any 待转换的值
返回
Array
如果value不是数组,返回转换后的数组
如果value是数组,返回value
源码
源码中涉及的函数
var isArray = require('./isArray');
/**
* Casts `value` as an array if it's not one.
*
* @static
* @memberOf _
* @since 4.4.0
* @category Lang
* @param {*} value The value to inspect.
* @returns {Array} Returns the cast array.
* @example
*
* _.castArray(1);
* // => [1]
*
* _.castArray({ 'a': 1 });
* // => [{ 'a': 1 }]
*
* _.castArray('abc');
* // => ['abc']
*
* _.castArray(null);
* // => [null]
*
* _.castArray(undefined);
* // => [undefined]
*
* _.castArray();
* // => []
*
* var array = [1, 2, 3];
* console.log(_.castArray(array) === array);
* // => true
*/
function castArray() {
if (!arguments.length) {
return [];
}
var value = arguments[0];
return isArray(value) ? value : [value];
}
module.exports = castArray;
ceil向上舍入
ceil(number, [precision=0])
Computes
number
rounded up toprecision
.根据 precision(精度) 向上舍入 number。(注: precision(精度)可以理解为保留几位小数。)
参数
-
number number 待操作值
-
precision number 可选 精度,保留的小数位数 默认precision=0
返回
number
舍入后的值
源码
源码中涉及的函数
var createRound = require('./_createRound');
/**
* Computes `number` rounded up to `precision`.
*
* @static
* @memberOf _
* @since 3.10.0
* @category Math
* @param {number} number The number to round up.
* @param {number} [precision=0] The precision to round up to.
* @returns {number} Returns the rounded up number.
* @example
*
* _.ceil(4.006);
* // => 5
*
* _.ceil(6.004, 2);
* // => 6.01
*
* _.ceil(6040, -2);
* // => 6100
*/
var ceil = createRound('ceil');
module.exports = ceil;
chunk数组拆分重组
chunk(array,[size],[guard])
将数组(array)拆分成多个 size 长度的区块,并将这些区块组成一个新数组。 如果array 无法被分割成全部等长的区块,那么最后剩余的元素将组成一个区块。
Creates an array of elements split into groups the length of
size
.创建一个元素数组,分成长度为’ size '的组。
If
array
can’t be split evenly, the final chunk will be the remaining elements如果’ array '不能被平均分割,最后的块将是剩余的元素
参数
- array 待分割的数组
- size 可选 默认为1 每个数组区块的长度
- guard 可选 允许像’ _.map '这样的方法使用作为迭代对象。true/false
返回
Array
返回拆分重组后的数组
用例1
console.log(chunk(['a', 'b', 'c', 'd'], 2))
//[ [ 'a', 'b' ], [ 'c', 'd' ] ]
console.log(chunk(['a', 'b', 'c', 'd'], 3))
//[ [ 'a', 'b', 'c' ], [ 'd' ] ]
console.log(chunk(['a', 'b', 'c', 'd']))
//[ [ 'a' ], [ 'b' ], [ 'c' ], [ 'd' ] ]
用例2
let a = ['a', 'b', 'c', 'd']
let b = chunk(a, 2)
console.log(b)
//[ [ 'a', 'b' ], [ 'c', 'd' ] ]
console.log(a)
//[ 'a', 'b', 'c', 'd' ]
let a = [{ a: 1 }, { b: 1 }]
let b = chunk(a)
a[0].a = 2
b[1][0].b = 2
console.log(b)
//[ [ { a: 2 } ], [ { b: 2 } ] ]
console.log(a)
//[ { a: 2 }, { b: 2 } ]
因此chunk虽然返回的是一个新数组,但是当数组中的值是一个对象时,它返回的是这个对象的引用
用例3
console.log([['a', 'b', 'c', 'd'], [1, 2, 3, 4, 5]].map(i => chunk(i, 2, true)))
//[ [ [ 'a', 'b' ], [ 'c', 'd' ] ], [ [ 1, 2 ], [ 3, 4 ], [ 5 ] ] ]
解析
function chunk(array, size, guard) {
//是否传入guard,如果传入,判断是否是遍历方法的参数,如果是size=1,否则为传入size和0的最大值
if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
size = 1;
} else {
//在size和0之间选个较大值
size = nativeMax(toInteger(size), 0);
}
var length = array == null ? 0 : array.length;
//如果length===0或者想要划分的模块大小小于1,返回空数组
if (!length || size < 1) {
return [];
}
var index = 0,
resIndex = 0,
result = Array(nativeCeil(length / size));
//建一个长度为length/size的数组存放结果
console.log('result:', result)
//result: [ <2 empty items> ]
while (index < length) {
//添加划分的数组
result[resIndex++] = baseSlice(array, index, (index += size));
}
return result;
}
console.log(chunk(['a', 'b', 'c', 'd'], 2))
源码
源码中涉及的方法
var baseSlice = require('./_baseSlice'),
isIterateeCall = require('./_isIterateeCall'),
toInteger = require('./toInteger');
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeCeil = Math.ceil,
nativeMax = Math.max;
/**
* Creates an array of elements split into groups the length of `size`.
* If `array` can't be split evenly, the final chunk will be the remaining
* elements.
*
* @static
* @memberOf _
* @since 3.0.0
* @category Array
* @param {Array} array The array to process.
* @param {number} [size=1] The length of each chunk
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
* @returns {Array} Returns the new array of chunks.
* @example
*
* _.chunk(['a', 'b', 'c', 'd'], 2);
* // => [['a', 'b'], ['c', 'd']]
*
* _.chunk(['a', 'b', 'c', 'd'], 3);
* // => [['a', 'b', 'c'], ['d']]
*/
function chunk(array, size, guard) {
if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
size = 1;
} else {
size = nativeMax(toInteger(size), 0);
}
var length = array == null ? 0 : array.length;
if (!length || size < 1) {
return [];
}
var index = 0,
resIndex = 0,
result = Array(nativeCeil(length / size));
while (index < length) {
result[resIndex++] = baseSlice(array, index, (index += size));
}
return result;
}
module.exports = chunk;
compact数组假值过滤
compact(Array)
Creates an array with all falsey values removed. The values
false
,null
,0
,""
,undefined
, andNaN
are falsey.创建一个新数组,包含原数组中所有的非假值元素。例如false, null,0, “”, undefined, 和 NaN 都是被认为是“假值”。
参数
- array 需要过滤的数组
返回
Array
过滤后的新数组
源码
/**
* Creates an array with all falsey values removed. The values `false`, `null`,
* `0`, `""`, `undefined`, and `NaN` are falsey.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Array
* @param {Array} array The array to compact.
* @returns {Array} Returns the new array of filtered values.
* @example
*
* _.compact([0, 1, false, 2, '', 3]);
* // => [1, 2, 3]
*/
function compact(array) {
//初始化变量
var index = -1,
length = array == null ? 0 : array.length,
resIndex = 0,
result = [];
//当index<length,即未遍历到底时
while (++index < length) {
//对于对象,这里是一个浅拷贝
var value = array[index];
if (value) {
result[resIndex++] = value;
}
}
return result;
}
concat数组连接
Creates a new array concatenating
array
with any additional arrays and/or values.创建一个新数组,将
array
与任何数组 或 值连接在一起。
参数
- array 第一个参数array是需要连接的原数组
- rest 剩余的参数是需要被array连接的数组或值
返回
Array
连接后的的数组
示例1
let a = [1]
let b = concat(a, 2, '3', [4, 5])
console.log(b)
//[ 1, 2, '3', 4, 5 ]
如果某个参数是个数组,则会把这个数组中的每个子元素拼接到目标结果上
let a = [1]
let b = concat(a, 2, '3', [4, [-4, -5], 5])
console.log(b)
//[ 1, 2, '3', 4, [ -4, -5 ], 5 ]
[-4,-5]作为子元素被拼接
let a = [1]
let b = concat(a, 2, [], [[]], null, false, undefined, '')
console.log(b)
//[ 1, 2, [], null, false, undefined, '' ]
没有子元素时不会被拼接,但其它的假值会被拼接
let a = { a: 1 }
let c = { c: 2 }
let b = concat(a, c)
a.a = 3
c.c = 3
console.log(b)
//[ { a: 3 }, { c: 3 } ]
let a = [[1], 2, 3]
let c = [[-1], -2, -3]
let b = concat(a, c)
a[0].push(4)
c[0].push(-4)
console.log(b)
//[ [ 1, 4 ], 2, 3, [ -1, -4 ], -2, -3 ]
显然,对于对象依然是引用
解析
var arrayPush = require('./_arrayPush'),
baseFlatten = require('./_baseFlatten'),
copyArray = require('./_copyArray'),
isArray = require('./isArray');
/**
* Creates a new array concatenating `array` with any additional arrays
* and/or values.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Array
* @param {Array} array The array to concatenate.
* @param {...*} [values] The values to concatenate.
* @returns {Array} Returns the new concatenated array.
* @example
*
* var array = [1];
* var other = _.concat(array, 2, [3], [[4]]);
*
* console.log(other);
* // => [1, 2, 3, [4]]
*
* console.log(array);
* // => [1]
*/
function concat() {
//length表示参数数量
var length = arguments.length;
if (!length) {
//如果没有参数,直接返回空数组
return [];
}
console.log('length ', length)
//length 3
//array是等待拼接的数组,即第一个参数
var args = Array(length - 1),
array = arguments[0],
index = length;
//当index>0时
console.log('array ', array)
//array [ 1, 2, 3 ]
while (index--) {
//将剩余参数放入args中,从最后一个参数开始存放,如果参数是数组,依然将其整体存放
args[index - 1] = arguments[index];
}
console.log('args ', args)
//args [ 4, [ 5, 6 ], '-1': [ 1, 2, 3 ] ]
console.log('baseFlatten(args, 1) ', baseFlatten(args, 1))
//baseFlatten(args, 1) [ 4, 5, 6 ]
//如果array不是数组,将其转为数组,如果是数组,则获取它的拷贝,将args的一层展开(如果参数是数组,这里相当于取出
//它的子元素)push到array的拷贝或[array]中
return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
}
let a = [1, 2, 3]
let b = concat(a, 4, [5, 6])
console.log('b ', b)
//b [ 1, 2, 3, 4, 5, 6 ]
module.exports = concat;
源码
var arrayPush = require('./_arrayPush'),
baseFlatten = require('./_baseFlatten'),
copyArray = require('./_copyArray'),
isArray = require('./isArray');
/**
* Creates a new array concatenating `array` with any additional arrays
* and/or values.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Array
* @param {Array} array The array to concatenate.
* @param {...*} [values] The values to concatenate.
* @returns {Array} Returns the new concatenated array.
* @example
*
* var array = [1];
* var other = _.concat(array, 2, [3], [[4]]);
*
* console.log(other);
* // => [1, 2, 3, [4]]
*
* console.log(array);
* // => [1]
*/
function concat() {
var length = arguments.length;
if (!length) {
return [];
}
var args = Array(length - 1),
array = arguments[0],
index = length;
while (index--) {
args[index - 1] = arguments[index];
}
return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
}
module.exports = concat;
constant返回value
constant(value)
Creates a function that returns
value
.创建一个返回
value
的函数。
参数
- value any 待返回的值
返回
Function
返回一个新函数,这个新函数返回value
源码
/**
* Creates a function that returns `value`.
*
* @static
* @memberOf _
* @since 2.4.0
* @category Util
* @param {*} value The value to return from the new function.
* @returns {Function} Returns the new constant function.
* @example
*
* var objects = _.times(2, _.constant({ 'a': 1 }));
*
* console.log(objects);
* // => [{ 'a': 1 }, { 'a': 1 }]
*
* console.log(objects[0] === objects[1]);
* // => true
*/
function constant(value) {
return function() {
return value;
};
}
module.exports = constant;
countBy集合迭代统计
countBy(collection, [iteratee=_.identity])
Creates an object composed of keys generated from the results of running each element of
collection
thruiteratee
. The corresponding value of each key is the number of times the key was returned byiteratee
. The iteratee is invoked with one argument: (value).创建一个组成对象,key(键)是经过
iteratee
(迭代函数) 执行处理collection
中每个元素后返回的结果,每个key(键)对应的值是iteratee
(迭代函数)返回该key(键)的次数(注:迭代次数)。 iteratee 调用一个参数:(value)。
参数
- collection Array|Object 待统计的集合
- iteratee Function 可选 迭代器。迭代器的返回结果将作为最终统计结果的键(key),返回相同键(key)的次数将作为这个键的值(value)
返回
Object
返回统计结果组成的对象
示例
示例1
console.log(countBy([6.1, 4.2, 6.3], Math.floor))
//{ '4': 1, '6': 2 }
console.log(countBy(['one', 'two', 'three'], 'length'))
//{ '3': 2, '5': 1 }
示例2
console.log(countBy({ a: 1, b: 2, c: 1, d: 1 }, (val) => val))
//{ '1': 3, '2': 1 }
源码
源码中涉及的函数
var baseAssignValue = require('./_baseAssignValue'),
createAggregator = require('./_createAggregator');
/** Used for built-in method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Creates an object composed of keys generated from the results of running
* each element of `collection` thru `iteratee`. The corresponding value of
* each key is the number of times the key was returned by `iteratee`. The
* iteratee is invoked with one argument: (value).
*
* @static
* @memberOf _
* @since 0.5.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} [iteratee=_.identity] The iteratee to transform keys.
* @returns {Object} Returns the composed aggregate object.
* @example
*
* _.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 }
*/
//创建一个聚合函数,function作为setter参数传入
var countBy = createAggregator(function(result, value, key) {
if (hasOwnProperty.call(result, key)) {
++result[key];
} else {
baseAssignValue(result, key, 1);
}
});
module.exports = countBy;
curry函数柯里化
curry(func, [arity=func.length])
Creates a function that accepts arguments of
func
and either invokesfunc
returning its result, if at leastarity
number of arguments have been provided, or returns a function that accepts the remainingfunc
arguments, and so on. The arity offunc
may be specified iffunc.length
is not sufficient.The
_.curry.placeholder
value, which defaults to_
in monolithic builds, may be used as a placeholder for provided arguments.Note: This method doesn’t set the “length” property of curried functions.
创建一个函数,该函数接收
func
的参数,要么调用func
返回的结果,如果func
所需参数已经提供,则直接返回func
所执行的结果。或返回一个函数,接受余下的func
参数的函数,可以使用func.length
强制需要累积的参数个数。
_.curry.placeholder
值,默认是以_
作为附加部分参数的占位符。Note: 这个方法不会设置 curried 函数的 “length” 属性。
参数
- func Function 待柯里化的函数
- arity number 可选 需要提供给
func
的参数数量,默认arity=func.length; func.length指func参数数量 - guard Object 可选 迭代守卫
返回
Function
返回新的柯里化函数
示例
示例1
var abc = function (a, b, c) {
const res = a + b + c
console.log(`${a}+${b}+${c}=${res}`)
return res;
};
var curried = curry(abc);
curried(1)(2)(3)//1+2+3=6
curried(1, 2, 3)//1+2+3=6
curried(1, 2)(3)//1+2+3=6
res = curried(1)
res = res(2)
res = res(3)//1+2+3=6
源码
源码中涉及到的函数
var createWrap = require('./_createWrap');
/** Used to compose bitmasks for function metadata. */
var WRAP_CURRY_FLAG = 8;
/**
* Creates a function that accepts arguments of `func` and either invokes
* `func` returning its result, if at least `arity` number of arguments have
* been provided, or returns a function that accepts the remaining `func`
* arguments, and so on. The arity of `func` may be specified if `func.length`
* is not sufficient.
*
* The `_.curry.placeholder` value, which defaults to `_` in monolithic builds,
* may be used as a placeholder for provided arguments.
*
* **Note:** This method doesn't set the "length" property of curried functions.
*
* @static
* @memberOf _
* @since 2.0.0
* @category Function
* @param {Function} func The function to curry.
* @param {number} [arity=func.length] The arity of `func`.
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
* @returns {Function} Returns the new curried function.
* @example
*
* 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, 2, 3]
*/
function curry(func, arity, guard) {
arity = guard ? undefined : arity;
var result = createWrap(func, WRAP_CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
result.placeholder = curry.placeholder;
return result;
}
// Assign default placeholders.
curry.placeholder = {};
module.exports = curry;
curryRight函数柯里化倒序接收附加参数
curryRight(func, [arity=func.length])
This method is like
_.curry
except that arguments are applied tofunc
in the manner of_.partialRight
instead of_.partial
.The
_.curryRight.placeholder
value, which defaults to_
in monolithic builds, may be used as a placeholder for provided arguments.Note: This method doesn’t set the “length” property of curried functions.
这个方法类似_.curry。除了它接受参数的方式用_.partialRight 代替了_.partial。
_.curryRight.placeholder值,默认是以 _ 作为附加部分参数的占位符。
Note: 这个方法不会设置 curried 函数的 “length” 属性。
参数
- func Function 待柯里化函数
- arity number 可选 需要提供给
func
的参数数量 默认arity=func.length func.length为函数参数数量 - guard Object 可选 迭代守卫
返回
Function
返回新的柯里化函数
源码
源码中涉及到的函数
var createWrap = require('./_createWrap');
/** Used to compose bitmasks for function metadata. */
var WRAP_CURRY_RIGHT_FLAG = 16;
/**
* This method is like `_.curry` except that arguments are applied to `func`
* in the manner of `_.partialRight` instead of `_.partial`.
*
* The `_.curryRight.placeholder` value, which defaults to `_` in monolithic
* builds, may be used as a placeholder for provided arguments.
*
* **Note:** This method doesn't set the "length" property of curried functions.
*
* @static
* @memberOf _
* @since 3.0.0
* @category Function
* @param {Function} func The function to curry.
* @param {number} [arity=func.length] The arity of `func`.
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
* @returns {Function} Returns the new curried function.
* @example
*
* var abc = function(a, b, c) {
* return [a, b, c];
* };
*
* var curried = _.curryRight(abc);
*
* curried(3)(2)(1);
* // => [1, 2, 3]
*
* curried(2, 3)(1);
* // => [1, 2, 3]
*
* curried(1, 2, 3);
* // => [1, 2, 3]
*
* // Curried with placeholders.
* curried(3)(1, _)(2);
* // => [1, 2, 3]
*/
function curryRight(func, arity, guard) {
arity = guard ? undefined : arity;
var result = createWrap(func, WRAP_CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity);
result.placeholder = curryRight.placeholder;
return result;
}
// Assign default placeholders.
curryRight.placeholder = {};
module.exports = curryRight;
debounce函数防抖
debounce(func, [wait=0], [options=])
Creates a debounced function that delays invoking
func
until afterwait
milliseconds have elapsed since the last time the debounced function was invoked. The debounced function comes with acancel
method to cancel delayedfunc
invocations and aflush
method to immediately invoke them. Provideoptions
to indicate whetherfunc
should be invoked on the leading and/or trailing edge of thewait
timeout. Thefunc
is invoked with the last arguments provided to the debounced function. Subsequent calls to the debounced function return the result of the lastfunc
invocation.Note: If
leading
andtrailing
options aretrue
,func
is invoked on the trailing edge of the timeout only if the debounced function is invoked more than once during thewait
timeout.If
wait
is0
andleading
isfalse
,func
invocation is deferred until to the next tick, similar tosetTimeout
with a timeout of0
.See David Corbacho’s article for details over the differences between
_.debounce
and_.throttle
.创建一个 debounced(防抖动)函数,该函数会从上一次被调用后,延迟
wait
毫秒后调用func
方法。 debounced(防抖动)函数提供一个cancel
方法取消延迟的函数调用以及flush
方法立即调用。 可以提供一个 options(选项) 对象决定如何调用func
方法,options.leading
与|或options.trailing
决定延迟前后如何触发(注:是 先调用后等待 还是 先等待后调用)。func
调用时会传入最后一次提供给 debounced(防抖动)函数 的参数。 后续调用的 debounced(防抖动)函数返回是最后一次func
调用的结果。注意: 如果
leading
和trailing
选项为true
, 则func
允许 trailing 方式调用的条件为: 在wait
期间多次调用防抖方法。如果
wait
为0
并且leading
为false
,func
调用将被推迟到下一个点,类似setTimeout
为0
的超时。
参数
- func Function 待包装函数
- wait number 可选 需要延迟的毫秒数
- options Object 可选 配置对象
- leading boolean 可选 指定在延迟开始前调用 默认 leading=false
- maxWait number 可选 设置func允许被延迟的最大值
- trailing boolean 可选 指定在延迟结束后调用 默认 trailing=true
返回
Function
返回新的 debounced(防抖动)函数
解析
var isObject = require('./isObject'),
now = require('./now'),
toNumber = require('./toNumber');
/** Error message constants. */
var FUNC_ERROR_TEXT = 'Expected a function';
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max,
nativeMin = Math.min;
/**
* Creates a debounced function that delays invoking `func` until after `wait`
* milliseconds have elapsed since the last time the debounced function was
* invoked. The debounced function comes with a `cancel` method to cancel
* delayed `func` invocations and a `flush` method to immediately invoke them.
* Provide `options` to indicate whether `func` should be invoked on the
* leading and/or trailing edge of the `wait` timeout. The `func` is invoked
* with the last arguments provided to the debounced function. Subsequent
* calls to the debounced function return the result of the last `func`
* invocation.
*
* **Note:** If `leading` and `trailing` options are `true`, `func` is
* invoked on the trailing edge of the timeout only if the debounced function
* is invoked more than once during the `wait` timeout.
*
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
* until to the next tick, similar to `setTimeout` with a timeout of `0`.
*
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
* for details over the differences between `_.debounce` and `_.throttle`.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Function
* @param {Function} func The function to debounce.
* @param {number} [wait=0] The number of milliseconds to delay.
* @param {Object} [options={}] The options object.
* @param {boolean} [options.leading=false]
* Specify invoking on the leading edge of the timeout.
* @param {number} [options.maxWait]
* The maximum time `func` is allowed to be delayed before it's invoked.
* @param {boolean} [options.trailing=true]
* Specify invoking on the trailing edge of the timeout.
* @returns {Function} Returns the new debounced function.
* @example
*
* // 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
* }));
*
* // Ensure `batchLog` is invoked once after 1 second of debounced calls.
* var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
* var source = new EventSource('/stream');
* jQuery(source).on('message', debounced);
*
* // Cancel the trailing debounced invocation.
* jQuery(window).on('popstate', debounced.cancel);
*/
function debounce(func, wait, options) {
var lastArgs,//上次调用参数
lastThis,//上次调用时的this
maxWait,//最大延迟时间毫秒数,保证func在maxWait时间段内最少执行一次,这主要用于throttle
result,
timerId,//定时执行
lastCallTime,//上次调用debounced时间,注意,是debounced
lastInvokeTime = 0,//上次执行时间
leading = false,
maxing = false,
trailing = true;
//func必须是函数,否则抛出异常
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
//延迟时间转为有效的值
wait = toNumber(wait) || 0;
if (isObject(options)) {
leading = !!options.leading;
maxing = 'maxWait' in options;
//如果配置中存在maxWait,则最大延迟时间取maxWait和wait之间的较大值
maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
trailing = 'trailing' in options ? !!options.trailing : trailing;
}
function invokeFunc(time) {
var args = lastArgs,
thisArg = lastThis;
//更新lastArgs与lastThis为undefined
lastArgs = lastThis = undefined;
//更新lastInvokeTime
lastInvokeTime = time;
//存储并返回func执行结果
result = func.apply(thisArg, args);
return result;
}
function leadingEdge(time) {
// Reset any `maxWait` timer.
//更新最后一次执行func时间
lastInvokeTime = time;
// Start the timer for the trailing edge.
//开始timer
timerId = setTimeout(timerExpired, wait);
// Invoke the leading edge.
//如果leading为true,调用func,否则返回result
return leading ? invokeFunc(time) : result;
}
//获取还应等待的时间
function remainingWait(time) {
var timeSinceLastCall = time - lastCallTime,
timeSinceLastInvoke = time - lastInvokeTime,
//等待时间为需要延迟的时间减去距离上次调用的时间
timeWaiting = wait - timeSinceLastCall;
//如果存在最大延迟时间,则返回timeWaiting与maxWait - timeSinceLastInvoke之间的较小值
return maxing
? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
: timeWaiting;
}
//判断是否应该被调用,time是当前时间戳
function shouldInvoke(time) {
//获取距离上一次调用与执行的时长
var timeSinceLastCall = time - lastCallTime,
timeSinceLastInvoke = time - lastInvokeTime;
// Either this is the first call, activity has stopped and we're at the
// trailing edge, the system time has gone backwards and we're treating
// it as the trailing edge, or we've hit the `maxWait` limit.
//当这是第一次调用denounced(这是debounce返回的防抖函数),或者距离上次调用已大于等于wait,
//或者距离上次执行func的时长大于等于最大延迟时间时返回true
return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
(timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
}
//刷新timer
function timerExpired() {
var time = now();
//如果可以执行func,调用trailingEdge
if (shouldInvoke(time)) {
return trailingEdge(time);
}
//重置timer
// Restart the timer.
timerId = setTimeout(timerExpired, remainingWait(time));
}
function trailingEdge(time) {
timerId = undefined;
// Only invoke if we have `lastArgs` which means `func` has been
// debounced at least once.
//当指定在延迟结束后调用并且存在lastArgs时调用func返回结果(存在lastArgs意味着debounced至少被调用了一次,而这次
//调用中func的执行被延迟到了现在)
if (trailing && lastArgs) {
return invokeFunc(time);
}
//清除lastArgs和lastThis
lastArgs = lastThis = undefined;
return result;
}
//取消
function cancel() {
if (timerId !== undefined) {
clearTimeout(timerId);
}
lastInvokeTime = 0;
lastArgs = lastCallTime = lastThis = timerId = undefined;
}
function flush() {
return timerId === undefined ? result : trailingEdge(now());
}
//返回的防抖函数
function debounced() {
//获取当前时间戳
var time = now(),
//判断是否可调用
isInvoking = shouldInvoke(time);
lastArgs = arguments;//调用时的参数
lastThis = this;
lastCallTime = time;//更新调用debounced的时刻
if (isInvoking) {
if (timerId === undefined) {
//如果timer===undefined,要么是第一次,要么前面的debounced调用已结束,或者其它原因,比如cancel之类
return leadingEdge(lastCallTime);
}
//如果存在最大延迟时间,并且timer存在,重设timer并返回执行结果
if (maxing) {
// Handle invocations in a tight loop.
clearTimeout(timerId);
timerId = setTimeout(timerExpired, wait);
return invokeFunc(lastCallTime);
}
}
//第一次调用设置timer
if (timerId === undefined) {
timerId = setTimeout(timerExpired, wait);
}
return result;
}
debounced.cancel = cancel;
debounced.flush = flush;
return debounced;
}
module.exports = debounce;
源码
源码中涉及到的函数
var isObject = require('./isObject'),
now = require('./now'),
toNumber = require('./toNumber');
/** Error message constants. */
var FUNC_ERROR_TEXT = 'Expected a function';
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max,
nativeMin = Math.min;
/**
* Creates a debounced function that delays invoking `func` until after `wait`
* milliseconds have elapsed since the last time the debounced function was
* invoked. The debounced function comes with a `cancel` method to cancel
* delayed `func` invocations and a `flush` method to immediately invoke them.
* Provide `options` to indicate whether `func` should be invoked on the
* leading and/or trailing edge of the `wait` timeout. The `func` is invoked
* with the last arguments provided to the debounced function. Subsequent
* calls to the debounced function return the result of the last `func`
* invocation.
*
* **Note:** If `leading` and `trailing` options are `true`, `func` is
* invoked on the trailing edge of the timeout only if the debounced function
* is invoked more than once during the `wait` timeout.
*
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
* until to the next tick, similar to `setTimeout` with a timeout of `0`.
*
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
* for details over the differences between `_.debounce` and `_.throttle`.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Function
* @param {Function} func The function to debounce.
* @param {number} [wait=0] The number of milliseconds to delay.
* @param {Object} [options={}] The options object.
* @param {boolean} [options.leading=false]
* Specify invoking on the leading edge of the timeout.
* @param {number} [options.maxWait]
* The maximum time `func` is allowed to be delayed before it's invoked.
* @param {boolean} [options.trailing=true]
* Specify invoking on the trailing edge of the timeout.
* @returns {Function} Returns the new debounced function.
* @example
*
* // 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
* }));
*
* // Ensure `batchLog` is invoked once after 1 second of debounced calls.
* var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
* var source = new EventSource('/stream');
* jQuery(source).on('message', debounced);
*
* // Cancel the trailing debounced invocation.
* jQuery(window).on('popstate', debounced.cancel);
*/
function debounce(func, wait, options) {
var lastArgs,
lastThis,
maxWait,
result,
timerId,
lastCallTime,
lastInvokeTime = 0,
leading = false,
maxing = false,
trailing = true;
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
wait = toNumber(wait) || 0;
if (isObject(options)) {
leading = !!options.leading;
maxing = 'maxWait' in options;
maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
trailing = 'trailing' in options ? !!options.trailing : trailing;
}
function invokeFunc(time) {
var args = lastArgs,
thisArg = lastThis;
lastArgs = lastThis = undefined;
lastInvokeTime = time;
result = func.apply(thisArg, args);
return result;
}
function leadingEdge(time) {
// Reset any `maxWait` timer.
lastInvokeTime = time;
// Start the timer for the trailing edge.
timerId = setTimeout(timerExpired, wait);
// Invoke the leading edge.
return leading ? invokeFunc(time) : result;
}
function remainingWait(time) {
var timeSinceLastCall = time - lastCallTime,
timeSinceLastInvoke = time - lastInvokeTime,
timeWaiting = wait - timeSinceLastCall;
return maxing
? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
: timeWaiting;
}
function shouldInvoke(time) {
var timeSinceLastCall = time - lastCallTime,
timeSinceLastInvoke = time - lastInvokeTime;
// Either this is the first call, activity has stopped and we're at the
// trailing edge, the system time has gone backwards and we're treating
// it as the trailing edge, or we've hit the `maxWait` limit.
return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
(timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
}
function timerExpired() {
var time = now();
if (shouldInvoke(time)) {
return trailingEdge(time);
}
// Restart the timer.
timerId = setTimeout(timerExpired, remainingWait(time));
}
function trailingEdge(time) {
timerId = undefined;
// Only invoke if we have `lastArgs` which means `func` has been
// debounced at least once.
if (trailing && lastArgs) {
return invokeFunc(time);
}
lastArgs = lastThis = undefined;
return result;
}
function cancel() {
if (timerId !== undefined) {
clearTimeout(timerId);
}
lastInvokeTime = 0;
lastArgs = lastCallTime = lastThis = timerId = undefined;
}
function flush() {
return timerId === undefined ? result : trailingEdge(now());
}
function debounced() {
var time = now(),
isInvoking = shouldInvoke(time);
lastArgs = arguments;
lastThis = this;
lastCallTime = time;
if (isInvoking) {
if (timerId === undefined) {
return leadingEdge(lastCallTime);
}
if (maxing) {
// Handle invocations in a tight loop.
clearTimeout(timerId);
timerId = setTimeout(timerExpired, wait);
return invokeFunc(lastCallTime);
}
}
if (timerId === undefined) {
timerId = setTimeout(timerExpired, wait);
}
return result;
}
debounced.cancel = cancel;
debounced.flush = flush;
return debounced;
}
module.exports = debounce;
deburr转换基本拉丁字母
deburr([string=’’])
Deburrs
string
by converting Latin-1 Supplement and Latin Extended-A letters to basic Latin letters and removing combining diacritical marks.
参数
- string string 可选 待转换的字符串
返回
string
返回转换后的结果
源码
源码中涉及的函数
var deburrLetter = require('./_deburrLetter'),
toString = require('./toString');
/** Used to match Latin Unicode letters (excluding mathematical operators). */
var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g;
/** Used to compose unicode character classes. */
var rsComboMarksRange = '\\u0300-\\u036f',
reComboHalfMarksRange = '\\ufe20-\\ufe2f',
rsComboSymbolsRange = '\\u20d0-\\u20ff',
rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange;
/** Used to compose unicode capture groups. */
var rsCombo = '[' + rsComboRange + ']';
/**
* Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
* [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
*/
var reComboMark = RegExp(rsCombo, 'g');
/**
* Deburrs `string` by converting
* [Latin-1 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
* and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A)
* letters to basic Latin letters and removing
* [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
*
* @static
* @memberOf _
* @since 3.0.0
* @category String
* @param {string} [string=''] The string to deburr.
* @returns {string} Returns the deburred string.
* @example
*
* _.deburr('déjà vu');
* // => 'deja vu'
*/
function deburr(string) {
string = toString(string);
return string && string.replace(reLatin, deburrLetter).replace(reComboMark, '');
}
module.exports = deburr;
defer函数推迟调用
defer(func, [args])
Defers invoking the
func
until the current call stack has cleared. Any additional arguments are provided tofunc
when it’s invoked.推迟调用
func
,直到当前堆栈清理完毕。 调用时,任何附加的参数会传给func
。
参数
- func Function 待推迟调用的函数
- args …any 可选 rest 附加参数,调用func时传给它的参数
返回
number
返回计时器id
源码
源码中涉及到的函数
var baseDelay = require('./_baseDelay'),
baseRest = require('./_baseRest');
/**
* Defers invoking the `func` until the current call stack has cleared. Any
* additional arguments are provided to `func` when it's invoked.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Function
* @param {Function} func The function to defer.
* @param {...*} [args] The arguments to invoke `func` with.
* @returns {number} Returns the timer id.
* @example
*
* _.defer(function(text) {
* console.log(text);
* }, 'deferred');
* // => Logs 'deferred' after one millisecond.
*/
var defer = baseRest(function(func, args) {
//延迟一毫秒调用func
return baseDelay(func, 1, args);
});
module.exports = defer;
delay函数延迟调用
delay(func, wait, [args])
Invokes
func
afterwait
milliseconds. Any additional arguments are provided tofunc
when it’s invoked.延迟
wait
毫秒后调用func
。 调用时,任何附加的参数会传给func
。
参数
- func Function 要延迟的函数
- wait number 延迟时间 毫秒
- args …any 可选 rest 附加参数,调用时传给func
返回
number
返回计时器id
源码
源码中涉及到的函数
var baseDelay = require('./_baseDelay'),
baseRest = require('./_baseRest'),
toNumber = require('./toNumber');
/**
* Invokes `func` after `wait` milliseconds. Any additional arguments are
* provided to `func` when it's invoked.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Function
* @param {Function} func The function to delay.
* @param {number} wait The number of milliseconds to delay invocation.
* @param {...*} [args] The arguments to invoke `func` with.
* @returns {number} Returns the timer id.
* @example
*
* _.delay(function(text) {
* console.log(text);
* }, 1000, 'later');
* // => Logs 'later' after one second.
*/
var delay = baseRest(function(func, wait, args) {
return baseDelay(func, toNumber(wait) || 0, args);
});
module.exports = delay;
difference数组指定过滤
Creates an array of
array
values not included in the other given arrays using [SameValueZero
] for equality comparisons. The order and references of result values are determined by the first array.创建一个具有唯一array值的数组,每个值不包含在其他给定的数组中。(注:即创建一个新数组,这个数组中的值,为第一个数字(array 参数)排除了给定数组中的值。)该方法使用SameValueZero做相等比较。结果值的顺序是由第一个数组中的顺序确定。
注意: 不像_.pullAll,这个方法会返回一个新数组。
参数
- array Array 要检查的数组。
- values 可选(…Array): 排除的值。
返回
Array
返回一个过滤值后的新数组。
示例
示例1
let a = [1, 2, 3, 4, 5]
let b = []
let res = difference(a)
console.log('res', res)
//res [ 1, 2, 3, 4, 5 ]
let a = [{ a: 1 }, 2, 3, 4, 5]
let b = []
let res = difference(a)
a[0].a = -1
console.log('res', res)
res [ { a: -1 }, 2, 3, 4, 5 ]
第二个参数是可选的 没有第二个参数时,将返回原数组(对于数组中的对象,依然是浅拷贝)
示例2
基本使用
let a = [1, 2, 3, 4, 5]
let b = [2, 4]
let res = difference(a, b)
console.log('res', res)
//res [ 1, 3, 5 ]
let a = [1, { a: 2 }, 3, 4, 5, [6, 7], undefined, 4, undefined]
let b = [{ a: 2 }, 4, [6, 7], undefined, 999]
let res = difference(a, b)
console.log('res', res)
//res [ 1, { a: 2 }, 3, 5, [ 6, 7 ] ]
不会过滤复杂类型,因为是不同的引用
解析
var baseDifference = require('./_baseDifference'),
baseFlatten = require('./_baseFlatten'),
baseRest = require('./_baseRest'),
isArrayLikeObject = require('./isArrayLikeObject');
/**
* Creates an array of `array` values not included in the other given arrays
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* for equality comparisons. The order and references of result values are
* determined by the first array.
*
* **Note:** Unlike `_.pullAll`, this method returns a new array.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Array
* @param {Array} array The array to inspect.
* @param {...Array} [values] The values to exclude.
* @returns {Array} Returns the new array of filtered values.
* @see _.without, _.xor
* @example
*
* _.difference([2, 1], [2, 3]);
* // => [1]
*/
var difference = baseRest(function(array, values) {
return isArrayLikeObject(array)
//如果array是类数组,调用baseDifference方法,并且将所有过滤数组扁平化一级,比如difference(arr,[1,2],[3,4]) => baseDifference(arr,[1,2,3,4])
? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
: [];
});
module.exports = difference;
源码
源码中涉及的方法
var baseDifference = require('./_baseDifference'),
baseFlatten = require('./_baseFlatten'),
baseRest = require('./_baseRest'),
isArrayLikeObject = require('./isArrayLikeObject');
/**
* Creates an array of `array` values not included in the other given arrays
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* for equality comparisons. The order and references of result values are
* determined by the first array.
*
* **Note:** Unlike `_.pullAll`, this method returns a new array.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Array
* @param {Array} array The array to inspect.
* @param {...Array} [values] The values to exclude.
* @returns {Array} Returns the new array of filtered values.
* @see _.without, _.xor
* @example
*
* _.difference([2, 1], [2, 3]);
* // => [1]
*/
var difference = baseRest(function(array, values) {
return isArrayLikeObject(array)
? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
: [];
});
module.exports = difference;
differenceBy数组迭代过滤
This method is like
_.difference
except that it acceptsiteratee
which is invoked for each element ofarray
andvalues
to generate the criterion by which they’re compared. The order and references of result values are determined by the first array. The iteratee is invoked with one argument: (value).这个方法类似_.difference ,除了它接受一个 iteratee (注:迭代器), 调用array 和 values 中的每个元素以产生比较的标准。 结果值是从第一数组中选择。iteratee 会调用一个参数:(value)。(注:首先使用迭代器分别迭代array 和 values中的每个元素,返回的值作为比较值)。
参数
- array 要检查的数组
- values 可选 排除的值
- iteratee 可选 迭代器 调用array和values中的每个元素
返回
Array
过滤后的数组
示例
示例1
基本使用
let a = [1, 2, 3, 4, 5, 4]
let b = [2, 4]
let res = differenceBy(a, b)
console.log('res', res)
//res [ 1, 3, 5 ]
示例2
迭代器
let a = [2.1, 1.2]
let b = [2.3, 3.4]
let res = differenceBy(a, b, Math.floor)
console.log('res', res)
//res [ 1.2 ]
Math.floor 向下取整,a,b数组中的值会先向下取整,再进行比较
let a = [2.1, 1.2]
let b = [2.3, 3.4]
let res = differenceBy(a, b, console.log)
console.log('res', res)
//2.3
//3.4
//2.1
//1.2
//res []
迭代器的参数是a,b中的每个元素
迭代器简写
let a = [{ 'x': 2 }, { 'x': 1 }]
let b = [{ 'x': 1 }]
let res = differenceBy(a, b, 'x')
console.log('res', res)
//res [ { x: 2 } ]
这里会根据‘x’创建一个函数,这个函数的传入参数是a,b中的每个对象,返回值是对象的’x’属性的值
解析
var baseDifference = require('./_baseDifference'),
baseFlatten = require('./_baseFlatten'),
baseIteratee = require('./_baseIteratee'),
baseRest = require('./_baseRest'),
isArrayLikeObject = require('./isArrayLikeObject'),
last = require('./last');
/**
* This method is like `_.difference` except that it accepts `iteratee` which
* is invoked for each element of `array` and `values` to generate the criterion
* by which they're compared. The order and references of result values are
* determined by the first array. The iteratee is invoked with one argument:
* (value).
*
* **Note:** Unlike `_.pullAllBy`, this method returns a new array.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Array
* @param {Array} array The array to inspect.
* @param {...Array} [values] The values to exclude.
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
* @returns {Array} Returns the new array of filtered values.
* @example
*
* _.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 differenceBy = baseRest(function(array, values) {
//迭代器是values最后一个参数
var iteratee = last(values);
//如果是数组,说明没有传iteratee
if (isArrayLikeObject(iteratee)) {
iteratee = undefined;
}
//如果array是数组,调用baseFlatten将要排除的数组进行一层扁平化处理,使用baseIteratee生成迭代器方法,再调用数组过滤的基本实现方法baseDifference进行过滤
return isArrayLikeObject(array)
? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), baseIteratee(iteratee, 2))
: [];
});
module.exports = differenceBy;
源码
源码中涉及的方法
var baseDifference = require('./_baseDifference'),
baseFlatten = require('./_baseFlatten'),
baseIteratee = require('./_baseIteratee'),
baseRest = require('./_baseRest'),
isArrayLikeObject = require('./isArrayLikeObject'),
last = require('./last');
/**
* This method is like `_.difference` except that it accepts `iteratee` which
* is invoked for each element of `array` and `values` to generate the criterion
* by which they're compared. The order and references of result values are
* determined by the first array. The iteratee is invoked with one argument:
* (value).
*
* **Note:** Unlike `_.pullAllBy`, this method returns a new array.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Array
* @param {Array} array The array to inspect.
* @param {...Array} [values] The values to exclude.
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
* @returns {Array} Returns the new array of filtered values.
* @example
*
* _.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 differenceBy = baseRest(function(array, values) {
var iteratee = last(values);
if (isArrayLikeObject(iteratee)) {
iteratee = undefined;
}
return isArrayLikeObject(array)
? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), baseIteratee(iteratee, 2))
: [];
});
module.exports = differenceBy;
differenceWith数组条件过滤
differenceWith(array, [values], [comparator])
This method is like
_.difference
except that it acceptscomparator
which is invoked to compare elements ofarray
tovalues
. The order and references of result values are determined by the first array. The comparator is invoked with two arguments: (arrVal, othVal).这个方法类似_.difference ,除了它接受一个 comparator (注:比较器),它调用比较array,values中的元素。 结果值是从第一数组中选择。comparator 调用参数有两个:(arrVal, othVal)。
参数
- array 待过滤数组
- values 可选 排除的值
- comparator 可选 比较器 调用每个元素
返回
Array
过滤后的数组
示例
示例1
let a = [1, 2, 3]
let b = [1, 2, 9]
let res = differenceWith(a, b, console.log)
console.log('res', res)
// 1 1
// 1 2
// 1 9
// 2 1
// 2 2
// 2 9
// 3 1
// 3 2
// 3 9
// res[1, 2, 3]
比较器的参数是两个,第一个是要过滤的数组中的元素,第二个是要排除的数组中的元素
示例2
基本使用
let a = [1, 2, 3]
let b = [1, 2, 9]
let res = differenceWith(a, b, (x, y) => Math.pow(x, 2) === y)
console.log('res', res)
//res [ 2 ]
源码
源码中涉及的方法
var baseDifference = require('./_baseDifference'),
baseFlatten = require('./_baseFlatten'),
baseRest = require('./_baseRest'),
isArrayLikeObject = require('./isArrayLikeObject'),
last = require('./last');
/**
* This method is like `_.difference` except that it accepts `comparator`
* which is invoked to compare elements of `array` to `values`. The order and
* references of result values are determined by the first array. The comparator
* is invoked with two arguments: (arrVal, othVal).
*
* **Note:** Unlike `_.pullAllWith`, this method returns a new array.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Array
* @param {Array} array The array to inspect.
* @param {...Array} [values] The values to exclude.
* @param {Function} [comparator] The comparator invoked per element.
* @returns {Array} Returns the new array of filtered values.
* @example
*
* var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
*
* _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual);
* // => [{ 'x': 2, 'y': 1 }]
*/
var differenceWith = baseRest(function(array, values) {
var comparator = last(values);
if (isArrayLikeObject(comparator)) {
comparator = undefined;
}
return isArrayLikeObject(array)
? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator)
: [];
});
module.exports = differenceWith;
divide两数相除
divide(dividend, divisor)
Divide two numbers.
两数相除
参数
- dividend number 被除数
- divisor number 除数
返回
number
计算后的结果
源码
源码中涉及的函数
var createMathOperation = require('./_createMathOperation');
/**
* Divide two numbers.
*
* @static
* @memberOf _
* @since 4.7.0
* @category Math
* @param {number} dividend The first number in a division.
* @param {number} divisor The second number in a division.
* @returns {number} Returns the quotient.
* @example
*
* _.divide(6, 4);
* // => 1.5
*/
var divide = createMathOperation(function(dividend, divisor) {
return dividend / divisor;
}, 1);
module.exports = divide;
drop去除数组前n个元素
Creates a slice of
array
withn
elements dropped from the beginning.创建一个切片数组,去除array前面的n个元素。(n默认值为1。)
参数
- array 待处理数组
- n 可选 去除个数,默认为1
- guard 可选 是否允许作为迭代器使用
返回
Array
返回去除元素后的数组
源码
源码中涉及的方法
var baseSlice = require('./_baseSlice'),
toInteger = require('./toInteger');
/**
* Creates a slice of `array` with `n` elements dropped from the beginning.
*
* @static
* @memberOf _
* @since 0.5.0
* @category Array
* @param {Array} array The array to query.
* @param {number} [n=1] The number of elements to drop.
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
* @returns {Array} Returns the slice of `array`.
* @example
*
* _.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]
*/
function drop(array, n, guard) {
var length = array == null ? 0 : array.length;
if (!length) {
return [];
}
n = (guard || n === undefined) ? 1 : toInteger(n);
return baseSlice(array, n < 0 ? 0 : n, length);
}
module.exports = drop;
dropRight去除数组后n个元素
Creates a slice of
array
withn
elements dropped from the end.创建一个切片数组,去除array尾部的n个元素。(n默认值为1。)
参数
- array 待处理数组
- n 可选 去除个数,默认为1
- guard 可选 是否允许作为迭代器使用
返回
Array
返回去除元素后的数组
源码
源码中涉及的方法
var baseSlice = require('./_baseSlice'),
toInteger = require('./toInteger');
/**
* Creates a slice of `array` with `n` elements dropped from the end.
*
* @static
* @memberOf _
* @since 3.0.0
* @category Array
* @param {Array} array The array to query.
* @param {number} [n=1] The number of elements to drop.
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
* @returns {Array} Returns the slice of `array`.
* @example
*
* _.dropRight([1, 2, 3]);
* // => [1, 2]
*
* _.dropRight([1, 2, 3], 2);
* // => [1]
*
* _.dropRight([1, 2, 3], 5);
* // => []
*
* _.dropRight([1, 2, 3], 0);
* // => [1, 2, 3]
*/
function dropRight(array, n, guard) {
var length = array == null ? 0 : array.length;
if (!length) {
return [];
}
n = (guard || n === undefined) ? 1 : toInteger(n);
n = length - n;
return baseSlice(array, 0, n < 0 ? 0 : n);
}
module.exports = dropRight;
dropRightWhile数组尾部条件过滤
dropRightWhile(array, [predicate=_.identity])
Creates a slice of
array
excluding elements dropped from the end. Elements are dropped untilpredicate
returns falsey. The predicate is invoked with three arguments: (value, index, array).创建一个切片数组,去除array中从 predicate 返回假值开始到尾部的部分。predicate 会传入3个参数: (value, index, array)。
参数
- array 待操作数组
- predicate=_.identity 可选 判断方法
返回
Array
返回array剩余切片。即过滤后的数组。
示例
示例1
let users = [
{ 'user': 'barney', 'active': true },
{ 'user': 'fred', 'active': false },
{ 'user': 'pebbles', 'active': false }
];
let res = dropRightWhile(users, function (o) { return !o.active; })
console.log('res', res)
//res [ { user: 'barney', active: true } ]
示例2
let a = [1, 2, 3, 4, 5, 4, 3, 2, 1]
let res = dropRightWhile(a, (value) => value !== 3)
console.log('res', res)
//res[1, 2, 3, 4, 5, 4, 3]
被去除的数组长度满足最小
源码
源码中涉及的方法
var baseIteratee = require('./_baseIteratee'),
baseWhile = require('./_baseWhile');
/**
* Creates a slice of `array` excluding elements dropped from the end.
* Elements are dropped until `predicate` returns falsey. The predicate is
* invoked with three arguments: (value, index, array).
*
* @static
* @memberOf _
* @since 3.0.0
* @category Array
* @param {Array} array The array to query.
* @param {Function} [predicate=_.identity] The function invoked per iteration.
* @returns {Array} Returns the slice of `array`.
* @example
*
* var users = [
* { 'user': 'barney', 'active': true },
* { 'user': 'fred', 'active': false },
* { 'user': 'pebbles', 'active': false }
* ];
*
* _.dropRightWhile(users, function(o) { return !o.active; });
* // => objects for ['barney']
*
* // The `_.matches` iteratee shorthand.
* _.dropRightWhile(users, { 'user': 'pebbles', 'active': false });
* // => objects for ['barney', 'fred']
*
* // The `_.matchesProperty` iteratee shorthand.
* _.dropRightWhile(users, ['active', false]);
* // => objects for ['barney']
*
* // The `_.property` iteratee shorthand.
* _.dropRightWhile(users, 'active');
* // => objects for ['barney', 'fred', 'pebbles']
*/
function dropRightWhile(array, predicate) {
return (array && array.length)
? baseWhile(array, baseIteratee(predicate, 3), true, true)
: [];
}
module.exports = dropRightWhile;
eq值比较
eq(value, other)
comparison between two values to determine if they are equivalent.
采用SameValueZero标准进行两个参数的比较
参数
- value any 第一个比较值
- other any 第二个比较值
返回
boolean
相等返回true,否则返回false,如果value=NaN并且other=NaN也返回true
源码
/**
* Performs a
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* comparison between two values to determine if they are equivalent.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to compare.
* @param {*} other The other value to compare.
* @returns {boolean} Returns `true` if the values are equivalent, else `false`.
* @example
*
* var object = { 'a': 1 };
* var other = { 'a': 1 };
*
* _.eq(object, object);
* // => true
*
* _.eq(object, other);
* // => false
*
* _.eq('a', 'a');
* // => true
*
* _.eq('a', Object('a'));
* // => false
*
* _.eq(NaN, NaN);
* // => true
*/
function eq(value, other) {
return value === other || (value !== value && other !== other);
}
module.exports = eq;
every集合遍历检查
every(collection, [predicate=_.identity])
Checks if
predicate
returns truthy for all elements ofcollection
. Iteration is stopped oncepredicate
returns falsey. The predicate is invoked with three arguments: (value, index|key, collection).通过 predicate(断言函数) 检查 collection(集合)中的 所有 元素是否都返回真值。一旦 predicate(断言函数) 返回假值,迭代就马上停止。predicate(断言函数)调用三个参数: (value, index|key, collection)。
注意: 这个方法对于对于空集合返回 true,因为空集合的任何元素都是 true 。
参数
- collection Array|Object 待遍历检查的集合
- predicate Function 可选 检查函数
- guard boolean 可选 是否可以作为迭代器使用
返回
boolean
如果所有元素经 predicate(断言函数) 检查后都都返回真值,那么就返回true,否则返回 false 。
源码
源码中涉及的函数
var arrayEvery = require('./_arrayEvery'),
baseEvery = require('./_baseEvery'),
baseIteratee = require('./_baseIteratee'),
isArray = require('./isArray'),
isIterateeCall = require('./_isIterateeCall');
/**
* Checks if `predicate` returns truthy for **all** elements of `collection`.
* Iteration is stopped once `predicate` returns falsey. The predicate is
* invoked with three arguments: (value, index|key, collection).
*
* **Note:** This method returns `true` for
* [empty collections](https://en.wikipedia.org/wiki/Empty_set) because
* [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of
* elements of empty collections.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} [predicate=_.identity] The function invoked per iteration.
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
* @returns {boolean} Returns `true` if all elements pass the predicate check,
* else `false`.
* @example
*
* _.every([true, 1, null, 'yes'], Boolean);
* // => false
*
* var users = [
* { 'user': 'barney', 'age': 36, 'active': false },
* { 'user': 'fred', 'age': 40, 'active': false }
* ];
*
* // The `_.matches` iteratee shorthand.
* _.every(users, { 'user': 'barney', 'active': false });
* // => false
*
* // The `_.matchesProperty` iteratee shorthand.
* _.every(users, ['active', false]);
* // => true
*
* // The `_.property` iteratee shorthand.
* _.every(users, 'active');
* // => false
*/
function every(collection, predicate, guard) {
var func = isArray(collection) ? arrayEvery : baseEvery;
if (guard && isIterateeCall(collection, predicate, guard)) {
predicate = undefined;
}
return func(collection, baseIteratee(predicate, 3));
}
module.exports = every;
flip函数参数翻转
flip(func)
Creates a function that invokes
func
with arguments reversed.创建一个函数,调用
func
时候接收翻转的参数。
参数
- func Function 要翻转参数的函数
返回
Function
返回新函数
源码
源码中涉及到的函数
var createWrap = require('./_createWrap');
/** Used to compose bitmasks for function metadata. */
var WRAP_FLIP_FLAG = 512;
/**
* Creates a function that invokes `func` with arguments reversed.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Function
* @param {Function} func The function to flip arguments for.
* @returns {Function} Returns the new flipped function.
* @example
*
* var flipped = _.flip(function() {
* return _.toArray(arguments);
* });
*
* flipped('a', 'b', 'c', 'd');
* // => ['d', 'c', 'b', 'a']
*/
function flip(func) {
return createWrap(func, WRAP_FLIP_FLAG);
}
module.exports = flip;
fill数组填充
fill(array, value, [start], [end])
Fills elements of
array
withvalue
fromstart
up to, but not including,end
.使用 value 值来填充(替换) array,从start位置开始, 到end位置结束(但不包含end位置)。
注意:这个方法会改变 array(注:不是创建新数组)。
参数
- array Array 要填充改变的数组。
- value any 填充给 array 的值。
- start number 可选 开始位置(默认0)。
- end number 可选 结束位置(默认array.length)。
返回
Array
返回 array。
示例
示例1
let array = [1, 2, 3, 4, 5]
let res = fill(array, 'a', 1, 4)
console.log(res)
//[ 1, 'a', 'a', 'a', 5 ]
示例2
let array = [1, 2, 3, 4, 5]
let res = fill(array, ['a', 'b'], 1, 4)
console.log(res)
//[ 1, [ 'a', 'b' ], [ 'a', 'b' ], [ 'a', 'b' ], 5 ]
源码
源码中涉及的方法
- baseFill fill实现的关键方法
- isIterateeCall
var baseFill = require('./_baseFill'),
isIterateeCall = require('./_isIterateeCall');
/**
* Fills elements of `array` with `value` from `start` up to, but not
* including, `end`.
*
* **Note:** This method mutates `array`.
*
* @static
* @memberOf _
* @since 3.2.0
* @category Array
* @param {Array} array The array to fill.
* @param {*} value The value to fill `array` with.
* @param {number} [start=0] The start position.
* @param {number} [end=array.length] The end position.
* @returns {Array} Returns `array`.
* @example
*
* var array = [1, 2, 3];
*
* _.fill(array, 'a');
* console.log(array);
* // => ['a', 'a', 'a']
*
* _.fill(Array(3), 2);
* // => [2, 2, 2]
*
* _.fill([4, 6, 8, 10], '*', 1, 3);
* // => [4, '*', '*', 10]
*/
function fill(array, value, start, end) {
var length = array == null ? 0 : array.length;
if (!length) {
return [];
}
//这里为什么要判断是否是迭代调用呢?
if (start && typeof start != 'number' && isIterateeCall(array, value, start)) {
start = 0;
end = length;
}
return baseFill(array, value, start, end);
}
module.exports = fill;
filter集合过滤
filter(collection, [predicate=_.identity])
Iterates over elements of
collection
, returning an array of all elementspredicate
returns truthy for. The predicate is invoked with three arguments: (value, index|key, collection).遍历 collection(集合)元素,返回 predicate(断言函数)返回真值 的所有元素的数组。 predicate(断言函数)调用三个参数:(value, index|key, collection)。
参数
- collection Array|Object 待过滤集合
- predicate Array|Function|Object|string 可选 每次迭代调用的函数
返回
Array
返回一个新的过滤后的数组
源码
源码中涉及的函数
var arrayFilter = require('./_arrayFilter'),
baseFilter = require('./_baseFilter'),
baseIteratee = require('./_baseIteratee'),
isArray = require('./isArray');
/**
* Iterates over elements of `collection`, returning an array of all elements
* `predicate` returns truthy for. The predicate is invoked with three
* arguments: (value, index|key, collection).
*
* **Note:** Unlike `_.remove`, this method returns a new array.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} [predicate=_.identity] The function invoked per iteration.
* @returns {Array} Returns the new filtered array.
* @see _.reject
* @example
*
* 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']
*
* // The `_.matchesProperty` iteratee shorthand.
* _.filter(users, ['active', false]);
* // => objects for ['fred']
*
* // The `_.property` iteratee shorthand.
* _.filter(users, 'active');
* // => objects for ['barney']
*
* // Combining several predicates using `_.overEvery` or `_.overSome`.
* _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]]));
* // => objects for ['fred', 'barney']
*/
function filter(collection, predicate) {
var func = isArray(collection) ? arrayFilter : baseFilter;
return func(collection, baseIteratee(predicate, 3));
}
module.exports = filter;
find集合查询
find(collection, [predicate=_.identity], [fromIndex=0])
Iterates over elements of
collection
, returning the first elementpredicate
returns truthy for. The predicate is invoked with three arguments: (value, index|key, collection).遍历
collection
(集合)元素,返回predicate
(断言函数)第一个返回真值的第一个元素。predicate(断言函数)调用3个参数: (value, index|key, collection)。
参数
- collection Array|Object 待查询的集合
- predicate Array|Function|Object|string 可选 迭代方法 传入三个参数
- value 当前值
- index|key当前值的索引|键
- collection 集合
- fromIndex number 可选 开始搜索的起始位置
返回
any
如果存在匹配元素,返回匹配元素,否则返回undefined
示例
示例1
当集合是一个对象时的用法
var users = { 'user': 'barney', 'age': 36, 'active': true }
console.log(find(users, (value, key) => { return value === 36 }))
//36
var users = { 'user': 'barney', 'age': 36, 'active': true }
console.log(find(users, (value, key) => { return key === 'age' }))
//36
源码
源码中涉及的函数
var createFind = require('./_createFind'),
findIndex = require('./findIndex');
/**
* Iterates over elements of `collection`, returning the first element
* `predicate` returns truthy for. The predicate is invoked with three
* arguments: (value, index|key, collection).
*
* @static
* @memberOf _
* @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to inspect.
* @param {Function} [predicate=_.identity] The function invoked per iteration.
* @param {number} [fromIndex=0] The index to search from.
* @returns {*} Returns the matched element, else `undefined`.
* @example
*
* 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; });
* // => object for 'barney'
*
* // The `_.matches` iteratee shorthand.
* _.find(users, { 'age': 1, 'active': true });
* // => object for 'pebbles'
*
* // The `_.matchesProperty` iteratee shorthand.
* _.find(users, ['active', false]);
* // => object for 'fred'
*
* // The `_.property` iteratee shorthand.
* _.find(users, 'active');
* // => object for 'barney'
*/
var find = createFind(findIndex);
module.exports = find;
findIndex数组查询
findIndex(array, [predicate=_.identity], [fromIndex=0])
This method is like
_.find
except that it returns the index of the first elementpredicate
returns truthy for instead of the element itself.该方法类似_.find,区别是该方法返回第一个通过 predicate 判断为真值的元素的索引值(index),而不是元素本身。
参数
- array Array 待搜索数组
- predicate Array|Function|Object|string 可选 迭代方法,用于判断当前值是否是搜索的值
- fromIndex number 可选 搜索的起始位置,默认为0
返回
number
如果存在被搜索值,则返回它的索引,否则返回-1
示例
示例1
let users = [
{ 'user': 'barney', 'active': false },
{ 'user': 'fred', 'active': false },
{ 'user': 'pebbles', 'active': true }
];
let res = findIndex(users, function (o) { return o.user == 'barney'; })
console.log(res)
//0
示例2
let users = [
{ 'user': 'barney', 'active': false },
{ 'user': 'fred', 'active': false },
{ 'user': 'pebbles', 'active': true }
];
let res = findIndex(users, { 'user': 'fred', 'active': false })
console.log(res)
//1
示例3
let users = [
{ 'user': 'barney', 'active': false },
{ 'user': 'fred', 'active': false },
{ 'user': 'pebbles', 'active': true }
];
let res = findIndex(users, ['user', 'pebbles'])
console.log(res)
//2
示例4
let users = [
{ 'user': 'barney', 'active': false },
{ 'user': 'fred', 'active': false },
{ 'user': 'pebbles', 'active': true }
];
let res = findIndex(users, 'active')
console.log(res)
//2
源码
源码中涉及的方法
var baseFindIndex = require('./_baseFindIndex'),
baseIteratee = require('./_baseIteratee'),
toInteger = require('./toInteger');
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;
/**
* This method is like `_.find` except that it returns the index of the first
* element `predicate` returns truthy for instead of the element itself.
*
* @static
* @memberOf _
* @since 1.1.0
* @category Array
* @param {Array} array The array to inspect.
* @param {Function} [predicate=_.identity] The function invoked per iteration.
* @param {number} [fromIndex=0] The index to search from.
* @returns {number} Returns the index of the found element, else `-1`.
* @example
*
* var users = [
* { 'user': 'barney', 'active': false },
* { 'user': 'fred', 'active': false },
* { 'user': 'pebbles', 'active': true }
* ];
*
* _.findIndex(users, function(o) { return o.user == 'barney'; });
* // => 0
*
* // The `_.matches` iteratee shorthand.
* _.findIndex(users, { 'user': 'fred', 'active': false });
* // => 1
*
* // The `_.matchesProperty` iteratee shorthand.
* _.findIndex(users, ['active', false]);
* // => 0
*
* // The `_.property` iteratee shorthand.
* _.findIndex(users, 'active');
* // => 2
*/
function findIndex(array, predicate, fromIndex) {
var length = array == null ? 0 : array.length;
if (!length) {
return -1;
}
var index = fromIndex == null ? 0 : toInteger(fromIndex);
if (index < 0) {
index = nativeMax(length + index, 0);
}
return baseFindIndex(array, baseIteratee(predicate, 3), index);
}
module.exports = findIndex;
findLast集合倒序查询
findLast(collection, [predicate=_.identity], [fromIndex=collection.length-1])
This method is like
_.find
except that it iterates over elements ofcollection
from right to left.这个方法类似_.find ,不同之处在于,_.findLast是从右至左遍历collection (集合)元素的。
参数
- collection Array|Object 待查询的集合
- predicate Array|Function|Object|string 可选 迭代方法 传入三个参数
- value 当前值
- index|key当前值的索引|键
- collection 集合
- fromIndex number 可选 开始搜索的起始位置
返回
any
从右到左进行查找,返回满足条件的第一个元素
源码
源码中涉及的方法
var createFind = require('./_createFind'),
findLastIndex = require('./findLastIndex');
/**
* This method is like `_.find` except that it iterates over elements of
* `collection` from right to left.
*
* @static
* @memberOf _
* @since 2.0.0
* @category Collection
* @param {Array|Object} collection The collection to inspect.
* @param {Function} [predicate=_.identity] The function invoked per iteration.
* @param {number} [fromIndex=collection.length-1] The index to search from.
* @returns {*} Returns the matched element, else `undefined`.
* @example
*
* _.findLast([1, 2, 3, 4], function(n) {
* return n % 2 == 1;
* });
* // => 3
*/
var findLast = createFind(findLastIndex);
module.exports = findLast;
findLastIndex数组倒序查询
findLastIndex(array, [predicate=_.identity], [fromIndex=array.length-1])
This method is like
_.findIndex
except that it iterates over elements ofcollection
from right to left.这个方式类似_.findIndex, 区别是它是从右到左的迭代集合array中的元素。
参数
- array Array 待搜索的数组
- predicate Array|Function|Object|string 可选 这个函数会在每一次迭代调用,用于判断当前值是否是被搜索的值
- fromIndex number 可选 查询的起始位置,默认是array.length-1
返回
number
如果存在待搜索值,返回它的索引,否则返回-1
源码
源码中涉及的方法
var baseFindIndex = require('./_baseFindIndex'),
baseIteratee = require('./_baseIteratee'),
toInteger = require('./toInteger');
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max,
nativeMin = Math.min;
/**
* This method is like `_.findIndex` except that it iterates over elements
* of `collection` from right to left.
*
* @static
* @memberOf _
* @since 2.0.0
* @category Array
* @param {Array} array The array to inspect.
* @param {Function} [predicate=_.identity] The function invoked per iteration.
* @param {number} [fromIndex=array.length-1] The index to search from.
* @returns {number} Returns the index of the found element, else `-1`.
* @example
*
* var users = [
* { 'user': 'barney', 'active': true },
* { 'user': 'fred', 'active': false },
* { 'user': 'pebbles', 'active': false }
* ];
*
* _.findLastIndex(users, function(o) { return o.user == 'pebbles'; });
* // => 2
*
* // The `_.matches` iteratee shorthand.
* _.findLastIndex(users, { 'user': 'barney', 'active': true });
* // => 0
*
* // The `_.matchesProperty` iteratee shorthand.
* _.findLastIndex(users, ['active', false]);
* // => 2
*
* // The `_.property` iteratee shorthand.
* _.findLastIndex(users, 'active');
* // => 0
*/
function findLastIndex(array, predicate, fromIndex) {
var length = array == null ? 0 : array.length;
if (!length) {
return -1;
}
var index = length - 1;
if (fromIndex !== undefined) {
index = toInteger(fromIndex);
index = fromIndex < 0
? nativeMax(length + index, 0)
: nativeMin(index, length - 1);
}
return baseFindIndex(array, baseIteratee(predicate, 3), index, true);
}
module.exports = findLastIndex;
flatMap迭代结果扁平化
flatMap(collection, [iteratee=_.identity])
Creates a flattened array of values by running each element in
collection
thruiteratee
and flattening the mapped results. The iteratee is invoked with three arguments: (value, index|key, collection).创建一个扁平化(注:同阶数组)的数组,这个数组的值来自
collection
(集合)中的每一个值经过iteratee
(迭代函数) 处理后返回的结果,并且扁平化合并。 iteratee 调用三个参数: (value, index|key, collection)。
注意:这个函数只会将结果展开一层
参数
- collection Array|Object 待处理集合
- iteratee Array|Function|Object|string 可选 迭代器 每次迭代调用
返回
Array
返回处理后的新的扁平化数组
源码
源码中涉及的函数
var baseFlatten = require('./_baseFlatten'),
map = require('./map');
/**
* Creates a flattened array of values by running each element in `collection`
* thru `iteratee` and flattening the mapped results. The iteratee is invoked
* with three arguments: (value, index|key, collection).
*
* @static
* @memberOf _
* @since 4.0.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @returns {Array} Returns the new flattened array.
* @example
*
* function duplicate(n) {
* return [n, n];
* }
*
* _.flatMap([1, 2], duplicate);
* // => [1, 1, 2, 2]
*/
function flatMap(collection, iteratee) {
return baseFlatten(map(collection, iteratee), 1);
}
module.exports = flatMap;
flatMapDeep迭代结果完全扁平化
flatMapDeep(collection, [iteratee=_.identity])
This method is like
_.flatMap
except that it recursively flattens the mapped results.这个方法类似_.flatMap 不同之处在于,_.flatMapDeep 会继续扁平化递归映射的结果。
参数
- collection Array|Object 待处理的集合
- iteratee Array|Function|Object|string 可选 迭代器 每次迭代调用
返回
Array
返回处理后的新的扁平化数组
源码
源码中涉及否函数
var baseFlatten = require('./_baseFlatten'),
map = require('./map');
/** Used as references for various `Number` constants. */
var INFINITY = 1 / 0;
/**
* This method is like `_.flatMap` except that it recursively flattens the
* mapped results.
*
* @static
* @memberOf _
* @since 4.7.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @returns {Array} Returns the new flattened array.
* @example
*
* function duplicate(n) {
* return [[[n, n]]];
* }
*
* _.flatMapDeep([1, 2], duplicate);
* // => [1, 1, 2, 2]
*/
function flatMapDeep(collection, iteratee) {
return baseFlatten(map(collection, iteratee), INFINITY);
}
module.exports = flatMapDeep;
flatMapDepth迭代结果指定层级展开
flatMapDepth(collection, [iteratee=_.identity], [depth=1])
This method is like
_.flatMap
except that it recursively flattens the mapped results up todepth
times.该方法类似_.flatMap,不同之处在于,_.flatMapDepth 会根据指定的 depth(递归深度)继续扁平化递归映射结果。
参数
- collection Array|Object 待处理的集合
- iteratee Array|Function|Object|string 可选 迭代器 每次迭代调用
- depth number 可选 最大递归深度,指定展开的层级,默认depth=1
返回
Array
返回处理后的新的指定层级展开的数组
源码
源码中涉及的函数
var baseFlatten = require('./_baseFlatten'),
map = require('./map'),
toInteger = require('./toInteger');
/**
* This method is like `_.flatMap` except that it recursively flattens the
* mapped results up to `depth` times.
*
* @static
* @memberOf _
* @since 4.7.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @param {number} [depth=1] The maximum recursion depth.
* @returns {Array} Returns the new flattened array.
* @example
*
* function duplicate(n) {
* return [[[n, n]]];
* }
*
* _.flatMapDepth([1, 2], duplicate, 2);
* // => [[1, 1], [2, 2]]
*/
function flatMapDepth(collection, iteratee, depth) {
depth = depth === undefined ? 1 : toInteger(depth);
return baseFlatten(map(collection, iteratee), depth);
}
module.exports = flatMapDepth;
flatten数组一级展开
flatten(array)
Flattens
array
a single level deep.减少一级
array
嵌套深度。
参数
- array Array 待展开的数组
返回
Array
展开后的新数组
示例
示例1
console.log(flatten([1, [2, [3, [4]], 5]]))
//[ 1, 2, [ 3, [ 4 ] ], 5 ]
源码
源码中涉及的方法
- baseFlatten flatten实现的基础方法
var baseFlatten = require('./_baseFlatten');
/**
* Flattens `array` a single level deep.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Array
* @param {Array} array The array to flatten.
* @returns {Array} Returns the new flattened array.
* @example
*
* _.flatten([1, [2, [3, [4]], 5]]);
* // => [1, 2, [3, [4]], 5]
*/
function flatten(array) {
var length = array == null ? 0 : array.length;
return length ? baseFlatten(array, 1) : [];
}
module.exports = flatten;
flattenDeep数组完全扁平化
flattenDeep(array)
Recursively flattens
array
.将
array
递归为一维数组。
参数
- array Array 待扁平化处理的数组
返回
Array
扁平化后的新数组
示例
示例1
console.log(flattenDeep([1, [2, [3, [4]], 5]]))
//[ 1, 2, 3, 4, 5 ]
源码
源码中涉及的方法
- baseFlatten flattenDeep实现的基础方法
var baseFlatten = require('./_baseFlatten');
/** Used as references for various `Number` constants. */
var INFINITY = 1 / 0;
/**
* Recursively flattens `array`.
*
* @static
* @memberOf _
* @since 3.0.0
* @category Array
* @param {Array} array The array to flatten.
* @returns {Array} Returns the new flattened array.
* @example
*
* _.flattenDeep([1, [2, [3, [4]], 5]]);
* // => [1, 2, 3, 4, 5]
*/
function flattenDeep(array) {
var length = array == null ? 0 : array.length;
//传入一个正无穷的值作为扁平化层级
return length ? baseFlatten(array, INFINITY) : [];
}
module.exports = flattenDeep;
flattenDepth数组指定层级展开
flattenDepth(array, [depth=1])
Recursively flatten
array
up todepth
times.根据
depth
递归减少array
的嵌套层级
参数
- array Array 待展开的数组
- depth number 可选 指定展开的层级 默认depth=1
返回
Array
展开后的新数组
示例
示例1
console.log(flattenDepth([1, [2, [3, [4]], 5]], 2))
//[ 1, 2, 3, [ 4 ], 5 ]
源码
源码中涉及的方法
var baseFlatten = require('./_baseFlatten'),
toInteger = require('./toInteger');
/**
* Recursively flatten `array` up to `depth` times.
*
* @static
* @memberOf _
* @since 4.4.0
* @category Array
* @param {Array} array The array to flatten.
* @param {number} [depth=1] The maximum recursion depth.
* @returns {Array} Returns the new flattened array.
* @example
*
* var array = [1, [2, [3, [4]], 5]];
*
* _.flattenDepth(array, 1);
* // => [1, 2, [3, [4]], 5]
*
* _.flattenDepth(array, 2);
* // => [1, 2, 3, [4], 5]
*/
function flattenDepth(array, depth) {
var length = array == null ? 0 : array.length;
if (!length) {
return [];
}
depth = depth === undefined ? 1 : toInteger(depth);
return baseFlatten(array, depth);
}
module.exports = flattenDepth;
floor向下舍入
floor(number, [precision=0])
Computes
number
rounded down toprecision
.根据 precision(精度) 向下舍入 number。(注: precision(精度)可以理解为保留几位小数。)
参数
- number number 待舍入的值
- precision number 可选 精度,保留的小数位数 默认precision=0
返回
number
舍入后的值
源码
源码中涉及的函数
var createRound = require('./_createRound');
/**
* Computes `number` rounded down to `precision`.
*
* @static
* @memberOf _
* @since 3.10.0
* @category Math
* @param {number} number The number to round down.
* @param {number} [precision=0] The precision to round down to.
* @returns {number} Returns the rounded down number.
* @example
*
* _.floor(4.006);
* // => 4
*
* _.floor(0.046, 2);
* // => 0.04
*
* _.floor(4060, -2);
* // => 4000
*/
var floor = createRound('floor');
module.exports = floor;
forEach集合遍历
forEach(collection, [iteratee=_.identity])
Iterates over elements of
collection
and invokesiteratee
for each element. The iteratee is invoked with three arguments: (value, index|key, collection). Iteratee functions may exit iteration early by explicitly returningfalse
.调用 iteratee 遍历 collection(集合) 中的每个元素, iteratee 调用3个参数: (value, index|key, collection)。 如果迭代函数(iteratee)显式的返回 false ,迭代会提前退出。
参数
- collection Array|Object 待遍历的集合
- iteratee Function 可选 迭代器 每次遍历调用
返回
any
返回集合 collection
源码
源码中涉及的函数
var arrayEach = require('./_arrayEach'),
baseEach = require('./_baseEach'),
castFunction = require('./_castFunction'),
isArray = require('./isArray');
/**
* Iterates over elements of `collection` and invokes `iteratee` for each element.
* The iteratee is invoked with three arguments: (value, index|key, collection).
* Iteratee functions may exit iteration early by explicitly returning `false`.
*
* **Note:** As with other "Collections" methods, objects with a "length"
* property are iterated like arrays. To avoid this behavior use `_.forIn`
* or `_.forOwn` for object iteration.
*
* @static
* @memberOf _
* @since 0.1.0
* @alias each
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @returns {Array|Object} Returns `collection`.
* @see _.forEachRight
* @example
*
* _.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).
*/
function forEach(collection, iteratee) {
var func = isArray(collection) ? arrayEach : baseEach;
return func(collection, castFunction(iteratee));
}
module.exports = forEach;
forEachRight集合反向遍历
forEachRight(collection, [iteratee=_.identity])
This method is like
_.forEach
except that it iterates over elements ofcollection
from right to left.这个方法类似_.forEach,不同之处在于,_.forEachRight 是从右到左遍历集合中每一个元素的。
参数
- collection Array|Object 待遍历的集合
- iteratee Function 迭代器
返回
Array|Object
返回集合
源码
源码中涉及的函数
var arrayEachRight = require('./_arrayEachRight'),
baseEachRight = require('./_baseEachRight'),
castFunction = require('./_castFunction'),
isArray = require('./isArray');
/**
* This method is like `_.forEach` except that it iterates over elements of
* `collection` from right to left.
*
* @static
* @memberOf _
* @since 2.0.0
* @alias eachRight
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @returns {Array|Object} Returns `collection`.
* @see _.forEach
* @example
*
* _.forEachRight([1, 2], function(value) {
* console.log(value);
* });
* // => Logs `2` then `1`.
*/
function forEachRight(collection, iteratee) {
var func = isArray(collection) ? arrayEachRight : baseEachRight;
return func(collection, castFunction(iteratee));
}
module.exports = forEachRight;
fromPairs数组转对象
fromPairs(pairs)
The inverse of
_.toPairs
; this method returns an object composed from key-valuepairs
.与[
toPairs
正好相反;这个方法返回一个由键值对pairs
构成的对象。
参数
- paris array 键值对
返回
Object
返回由键值对构成的新对象
示例
示例1
console.log(fromPairs([['a', 1], ['b', 2]]))
//{ a: 1, b: 2 }
示例2
console.log(fromPairs(['a', 1]))
//{ a: undefined, undefined: undefined }
示例3
console.log(fromPairs([[['a', 1]], [['b', 2]]]))
//{ 'a,1': undefined, 'b,2': undefined }
解析
/**
* The inverse of `_.toPairs`; this method returns an object composed
* from key-value `pairs`.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Array
* @param {Array} pairs The key-value pairs.
* @returns {Object} Returns the new object.
* @example
*
* _.fromPairs([['a', 1], ['b', 2]]);
* // => { 'a': 1, 'b': 2 }
*/
function fromPairs(pairs) {
var index = -1,
length = pairs == null ? 0 : pairs.length,
result = {};
//这里是先自增,再比较,从循环体中看出,pairs需要是一个二维数组,并且每个子数组的长度至少为2,长度超出2(索引大于1)
//的部分会被忽略
while (++index < length) {
var pair = pairs[index];
result[pair[0]] = pair[1];
}
return result;
}
module.exports = fromPairs;
源码
/**
* The inverse of `_.toPairs`; this method returns an object composed
* from key-value `pairs`.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Array
* @param {Array} pairs The key-value pairs.
* @returns {Object} Returns the new object.
* @example
*
* _.fromPairs([['a', 1], ['b', 2]]);
* // => { 'a': 1, 'b': 2 }
*/
function fromPairs(pairs) {
var index = -1,
length = pairs == null ? 0 : pairs.length,
result = {};
while (++index < length) {
var pair = pairs[index];
result[pair[0]] = pair[1];
}
return result;
}
module.exports = fromPairs;
groupBy集合迭代分组
groupBy(collection, [iteratee=_.identity])
Creates an object composed of keys generated from the results of running each element of
collection
thruiteratee
. The order of grouped values is determined by the order they occur incollection
. The corresponding value of each key is an array of elements responsible for generating the key. The iteratee is invoked with one argument: (value).创建一个对象,key 是
iteratee
遍历collection
(集合) 中的每个元素返回的结果。 分组值的顺序是由他们出现在collection
(集合) 中的顺序确定的。每个键对应的值负责生成 key 的元素组成的数组。iteratee 调用 1 个参数: (value)。
参数
- collection Array|Object 待分组的集合
- iteratee Array|Function|Object|string 迭代器 这个迭代函数用来转换key
返回
Object
返回一个组成聚合的对象
示例
示例1
console.log(groupBy(['one', 'two', 'three'], 'length'))
//{ '3': [ 'one', 'two' ], '5': [ 'three' ] }
源码
源码中涉及的函数
var baseAssignValue = require('./_baseAssignValue'),
createAggregator = require('./_createAggregator');
/** Used for built-in method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Creates an object composed of keys generated from the results of running
* each element of `collection` thru `iteratee`. The order of grouped values
* is determined by the order they occur in `collection`. The corresponding
* value of each key is an array of elements responsible for generating the
* key. The iteratee is invoked with one argument: (value).
*
* @static
* @memberOf _
* @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} [iteratee=_.identity] The iteratee to transform keys.
* @returns {Object} Returns the composed aggregate object.
* @example
*
* _.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'] }
*/
//创建聚合函数,function作为setter参数传入
var groupBy = createAggregator(function (result, value, key) {
if (hasOwnProperty.call(result, key)) {
result[key].push(value);
} else {
baseAssignValue(result, key, [value]);
}
});
module.exports = groupBy;
head获取数组第一个元素
head(array)
别名:first
Gets the first element of
array
.获取数组
array
的第一个元素。
参数
- array Array
返回
any
返回数组第一个元素,如果不存在则返回undefined
源码
/**
* Gets the first element of `array`.
*
* @static
* @memberOf _
* @since 0.1.0
* @alias first
* @category Array
* @param {Array} array The array to query.
* @returns {*} Returns the first element of `array`.
* @example
*
* _.head([1, 2, 3]);
* // => 1
*
* _.head([]);
* // => undefined
*/
function head(array) {
return (array && array.length) ? array[0] : undefined;
}
module.exports = head;
identity返回首个提供的参数
identity(value)
This method returns the first argument it receives.
这个方法返回首个提供的参数。
参数
- value any 待返回的值
返回
any
返回value
源码
/**
* This method returns the first argument it receives.
*
* @static
* @since 0.1.0
* @memberOf _
* @category Util
* @param {*} value Any value.
* @returns {*} Returns `value`.
* @example
*
* var object = { 'a': 1 };
*
* console.log(_.identity(object) === object);
* // => true
*/
function identity(value) {
return value;
}
module.exports = identity;
includes集合包含查询
includes(collection, value, [fromIndex=0])
Checks if
value
is incollection
. Ifcollection
is a string, it’s checked for a substring ofvalue
, otherwiseSameValueZero
is used for equality comparisons. IffromIndex
is negative, it’s used as the offset from the end ofcollection
.
参数
- collection Array|Object 待查询集合
- value any 待查询值
- fromIndex number 可选 开始查询的位置,默认fromIndex=0
返回
boolean
如果存在value返回true,否则返回false
源码
源码中涉及的函数
var baseIndexOf = require('./_baseIndexOf'),
isArrayLike = require('./isArrayLike'),
isString = require('./isString'),
toInteger = require('./toInteger'),
values = require('./values');
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;
/**
* Checks if `value` is in `collection`. If `collection` is a string, it's
* checked for a substring of `value`, otherwise
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* is used for equality comparisons. If `fromIndex` is negative, it's used as
* the offset from the end of `collection`.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Collection
* @param {Array|Object|string} collection The collection to inspect.
* @param {*} value The value to search for.
* @param {number} [fromIndex=0] The index to search from.
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
* @returns {boolean} Returns `true` if `value` is found, else `false`.
* @example
*
* _.includes([1, 2, 3], 1);
* // => true
*
* _.includes([1, 2, 3], 1, 2);
* // => false
*
* _.includes({ 'a': 1, 'b': 2 }, 1);
* // => true
*
* _.includes('abcd', 'bc');
* // => true
*/
function includes(collection, value, fromIndex, guard) {
collection = isArrayLike(collection) ? collection : values(collection);
fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0;
var length = collection.length;
if (fromIndex < 0) {
fromIndex = nativeMax(length + fromIndex, 0);
}
return isString(collection)
? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1)
: (!!length && baseIndexOf(collection, value, fromIndex) > -1);
}
module.exports = includes;
indexOf数组查询
indexOf(array, value, [fromIndex=0])
Gets the index at which the first occurrence of
value
is found inarray
usingSameValueZero
for equality comparisons. IffromIndex
is negative, it’s used as the offset from the end ofarray
.使用SameValueZero 等值比较,返回首次 value 在数组array中被找到的 索引值, 如果 fromIndex 为负值,将从数组array尾端索引进行匹配。
参数
- array Array 待查询数组
- value any 待查询值
- fromIndex number 可选 查询的起始位置
返回
number
返回value在array中的索引,如果不存在则返回-1
源码
源码中涉及的方法
- toInteger
- baseIndexOf indexOf的基础实现方法
var baseIndexOf = require('./_baseIndexOf'),
toInteger = require('./toInteger');
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max;
/**
* Gets the index at which the first occurrence of `value` is found in `array`
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* for equality comparisons. If `fromIndex` is negative, it's used as the
* offset from the end of `array`.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Array
* @param {Array} array The array to inspect.
* @param {*} value The value to search for.
* @param {number} [fromIndex=0] The index to search from.
* @returns {number} Returns the index of the matched value, else `-1`.
* @example
*
* _.indexOf([1, 2, 1, 2], 2);
* // => 1
*
* // Search from the `fromIndex`.
* _.indexOf([1, 2, 1, 2], 2, 2);
* // => 3
*/
function indexOf(array, value, fromIndex) {
var length = array == null ? 0 : array.length;
if (!length) {
return -1;
}
var index = fromIndex == null ? 0 : toInteger(fromIndex);
if (index < 0) {
index = nativeMax(length + index, 0);
}
return baseIndexOf(array, value, index);
}
module.exports = indexOf;
initial获取数组前length-2项
initial(array)
Gets all but the last element of
array
.获取数组
array
中除了最后一个元素之外的所有元素(注:去除数组array
中的最后一个元素)。
参数
- array Array 待处理数组
返回
Array
返回截取后的数组
示例
示例1
console.log(initial([1, 2, 3]))
//[ 1, 2 ]
源码
源码中涉及的方法
var baseSlice = require('./_baseSlice');
/**
* Gets all but the last element of `array`.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Array
* @param {Array} array The array to query.
* @returns {Array} Returns the slice of `array`.
* @example
*
* _.initial([1, 2, 3]);
* // => [1, 2]
*/
function initial(array) {
var length = array == null ? 0 : array.length;
return length ? baseSlice(array, 0, -1) : [];
}
module.exports = initial;
intersection数组交集
intersection([arrays])
Creates an array of unique values that are included in all given arrays using
SameValueZero
for equality comparisons. The order and references of result values are determined by the first array.创建唯一值的数组,这个数组包含所有给定数组都包含的元素,使用SameValueZero进行相等性比较。(注:可以理解为给定数组的交集)
参数
- arrays …Array 可选 待处理的数组
返回
Array
返回一个包含所有传入数组交集元素的新数组。
示例
示例1
console.log(intersection([2, 1], [2, 3]))//[ 2 ]
示例2
console.log(intersection([2, 1]))//[ 2, 1 ]
示例3
console.log(intersection())//[]
解析
var arrayMap = require('./_arrayMap'),
baseIntersection = require('./_baseIntersection'),
baseRest = require('./_baseRest'),
castArrayLikeObject = require('./_castArrayLikeObject');
/**
* Creates an array of unique values that are included in all given arrays
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* for equality comparisons. The order and references of result values are
* determined by the first array.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Array
* @param {...Array} [arrays] The arrays to inspect.
* @returns {Array} Returns the new array of intersecting values.
* @example
*
* _.intersection([2, 1], [2, 3]);
* // => [2]
*/
var intersection = baseRest(function (arrays) {
//对每一个参数调用castArrayLikeObject,将非数组参数转换为空数组
var mapped = arrayMap(arrays, castArrayLikeObject);
//如果mapped[0]!==arrays[0],说明第一个参数被强制转换为空数组[],交集为[]
//否则调用baseIntersection
return (mapped.length && mapped[0] === arrays[0])
? baseIntersection(mapped)
: [];
});
module.exports = intersection;
源码
源码中涉及的方法
var arrayMap = require('./_arrayMap'),
baseIntersection = require('./_baseIntersection'),
baseRest = require('./_baseRest'),
castArrayLikeObject = require('./_castArrayLikeObject');
/**
* Creates an array of unique values that are included in all given arrays
* using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* for equality comparisons. The order and references of result values are
* determined by the first array.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Array
* @param {...Array} [arrays] The arrays to inspect.
* @returns {Array} Returns the new array of intersecting values.
* @example
*
* _.intersection([2, 1], [2, 3]);
* // => [2]
*/
var intersection = baseRest(function(arrays) {
var mapped = arrayMap(arrays, castArrayLikeObject);
return (mapped.length && mapped[0] === arrays[0])
? baseIntersection(mapped)
: [];
});
module.exports = intersection;
intersectionBy数组迭代处理交集
intersectionBy([arrays], [iteratee=_.identity])
This method is like
_.intersection
except that it acceptsiteratee
which is invoked for each element of eacharrays
to generate the criterion by which they’re compared. The order and references of result values are determined by the first array. The iteratee is invoked with one argument: (value).这个方法类似_.intersection,区别是它接受一个 iteratee 调用每一个arrays的每个值以产生一个值,通过产生的值进行了比较。结果值是从第一数组中选择。iteratee 会传入一个参数:(value)。
参数
- arrays …Arrays 可选待处理的数组
- iteratee Function 迭代器 用于处理每个数组的每个值
返回
Array
返回一个包含所有传入数组交集元素的新数组。
示例
示例1
console.log(intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor))
//[ 2.1 ]
示例2
console.log(intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'))
//[ { x: 1 } ]
源码
源码中涉及的方法
var arrayMap = require('./_arrayMap'),
baseIntersection = require('./_baseIntersection'),
baseIteratee = require('./_baseIteratee'),
baseRest = require('./_baseRest'),
castArrayLikeObject = require('./_castArrayLikeObject'),
last = require('./last');
/**
* This method is like `_.intersection` except that it accepts `iteratee`
* which is invoked for each element of each `arrays` to generate the criterion
* by which they're compared. The order and references of result values are
* determined by the first array. The iteratee is invoked with one argument:
* (value).
*
* @static
* @memberOf _
* @since 4.0.0
* @category Array
* @param {...Array} [arrays] The arrays to inspect.
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
* @returns {Array} Returns the new array of intersecting values.
* @example
*
* _.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 intersectionBy = baseRest(function(arrays) {
var iteratee = last(arrays),
mapped = arrayMap(arrays, castArrayLikeObject);
//如果iteratee等于mapped最后一个,说明iteratee是个数组,不存在迭代器
if (iteratee === last(mapped)) {
iteratee = undefined;
} else {
mapped.pop();
}
return (mapped.length && mapped[0] === arrays[0])
? baseIntersection(mapped, baseIteratee(iteratee, 2))
: [];
});
module.exports = intersectionBy;
intersectionWith数组自定义交集
intersectionWith([arrays], [comparator])
This method is like
_.intersection
except that it acceptscomparator
which is invoked to compare elements ofarrays
. The order and references of result values are determined by the first array. The comparator is invoked with two arguments: (arrVal, othVal).这个方法类似_.intersection,区别是它接受一个 comparator 调用比较arrays中的元素。结果值是从第一数组中选择。comparator 会传入两个参数:(arrVal, othVal)。
参数
- arrays …Arrays 可选 待处理的数组
- comparator Function 可选 比较器 用于定义相交,即满足比较器条件的值被认为是相等/相交的
返回
Array
返回一个包含所有传入数组交集元素的新数组。
示例
示例1
var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }];
var others = [{ 'x': 1, 'y': 1 }, { 'x': 3, 'y': 2 }];
console.log(intersectionWith(objects, others, (obj1, obj2) => {
return obj1.x === obj2.x
}))
//[ { x: 1, y: 2 } ]
示例2
var objects = [{ 'x': 2, 'y': 2 }, { 'x': 1, 'y': 1 }];
var others = [{ 'x': 1, 'y': 3 }, { 'x': 3, 'y': 2 }];
console.log(intersectionWith(objects, others, (obj1, obj2) => {
return obj1.x == 1
}))
//[ { x: 1, y: 1 } ]
结果值是从第一数组中选择
源码
var arrayMap = require('./_arrayMap'),
baseIntersection = require('./_baseIntersection'),
baseRest = require('./_baseRest'),
castArrayLikeObject = require('./_castArrayLikeObject'),
last = require('./last');
/**
* This method is like `_.intersection` except that it accepts `comparator`
* which is invoked to compare elements of `arrays`. The order and references
* of result values are determined by the first array. The comparator is
* invoked with two arguments: (arrVal, othVal).
*
* @static
* @memberOf _
* @since 4.0.0
* @category Array
* @param {...Array} [arrays] The arrays to inspect.
* @param {Function} [comparator] The comparator invoked per element.
* @returns {Array} Returns the new array of intersecting values.
* @example
*
* 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 }]
*/
var intersectionWith = baseRest(function(arrays) {
var comparator = last(arrays),
mapped = arrayMap(arrays, castArrayLikeObject);
comparator = typeof comparator == 'function' ? comparator : undefined;
if (comparator) {
mapped.pop();
}
return (mapped.length && mapped[0] === arrays[0])
? baseIntersection(mapped, undefined, comparator)
: [];
});
module.exports = intersectionWith;
invokeMap集合迭代调用
invokeMap(collection, path, [args])
Invokes the method at
path
of each element incollection
, returning an array of the results of each invoked method. Any additional arguments are provided to each invoked method. Ifpath
is a function, it’s invoked for, andthis
bound to, each element incollection
.
参数
- collection Array|Object 待迭代处理的集合
- Array|Function|string 用来调用方法的路径 或 者每次迭代调用的函数。
- args …any 可选 rest参数 调用每个方法的参数
返回
Array
返回迭代处理后的结果数组。
示例
示例1
let res = invokeMap([2, 3, 4, 5], function (item) {
console.log('item', item);
console.log('this', this);
console.log(arguments);
return 'a'
}, 2222)
console.log(res)
// item 2222
// this[Number: 2]
// [Arguments] { '0': 2222 }
// item 2222
// this[Number: 3]
// [Arguments] { '0': 2222 }
// item 2222
// this[Number: 4]
// [Arguments] { '0': 2222 }
// item 2222
// this[Number: 5]
// [Arguments] { '0': 2222 }
// ['a', 'a', 'a', 'a']
示例2
let res = invokeMap([2, 3, 4, 5], function (e) {
return Math.pow(this, e)
}, 2)
console.log(res)
//[ 4, 9, 16, 25 ]
源码
源码中涉及的函数
var apply = require('./_apply'),
baseEach = require('./_baseEach'),
baseInvoke = require('./_baseInvoke'),
baseRest = require('./_baseRest'),
isArrayLike = require('./isArrayLike');
/**
* Invokes the method at `path` of each element in `collection`, returning
* an array of the results of each invoked method. Any additional arguments
* are provided to each invoked method. If `path` is a function, it's invoked
* for, and `this` bound to, each element in `collection`.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Array|Function|string} path The path of the method to invoke or
* the function invoked per iteration.
* @param {...*} [args] The arguments to invoke each method with.
* @returns {Array} Returns the array of results.
* @example
*
* _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort');
* // => [[1, 5, 7], [1, 2, 3]]
*
* _.invokeMap([123, 456], String.prototype.split, '');
* // => [['1', '2', '3'], ['4', '5', '6']]
*/
var invokeMap = baseRest(function(collection, path, args) {
var index = -1,
isFunc = typeof path == 'function',
result = isArrayLike(collection) ? Array(collection.length) : [];
baseEach(collection, function(value) {
result[++index] = isFunc ? apply(path, value, args) : baseInvoke(value, path, args);
});
return result;
});
module.exports = invokeMap;
isArray检查数组
isArray(value)
Checks if
value
is classified as anArray
object.检查 value 是否是 Array 类对象。
参数
- value any 待检查的值
返回
boolean
如果是数组,返回true,否则返回false
源码
/**
* Checks if `value` is classified as an `Array` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an array, else `false`.
* @example
*
* _.isArray([1, 2, 3]);
* // => true
*
* _.isArray(document.body.children);
* // => false
*
* _.isArray('abc');
* // => false
*
* _.isArray(_.noop);
* // => false
*/
var isArray = Array.isArray;
module.exports = isArray;
isArrayLike检查类数组
Checks if
value
is array-like. A value is considered array-like if it’s not a function and has avalue.length
that’s an integer greater than or equal to0
and less than or equal toNumber.MAX_SAFE_INTEGER
.检查 value 是否是类数组。 如果一个值被认为是类数组,那么它不是一个函数,并且value.length是个整数,大于等于 0,小于或等于 Number.MAX_SAFE_INTEGER。
参数
- value 待判定的值
返回
Boolean
是否是类数组
源码
源码中涉及的方法
/**
* Checks if `value` is array-like. A value is considered array-like if it's
* not a function and has a `value.length` that's an integer greater than or
* equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is array-like, else `false`.
* @example
*
* _.isArrayLike([1, 2, 3]);
* // => true
*
* _.isArrayLike(document.body.children);
* // => true
*
* _.isArrayLike('abc');
* // => true
*
* _.isArrayLike(_.noop);
* // => false
*/
function isArrayLike(value) {
return value != null && isLength(value.length) && !isFunction(value);
}
isArrayLikeObject检查类数组对象
This method is like
_.isArrayLike
except that it also checks ifvalue
is an object.检查是否是类数组对象,在类数组的基础上排除了string
这个方法类似_.isArrayLike。除了它还检查value是否是个对象。
参数
- value 需要检查的值
返回
boolean
如果是则返回true
源码
源码中涉及的方法
var isArrayLike = require('./isArrayLike'),
isObjectLike = require('./isObjectLike');
/**
* This method is like `_.isArrayLike` except that it also checks if `value`
* is an object.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an array-like object,
* else `false`.
* @example
*
* _.isArrayLikeObject([1, 2, 3]);
* // => true
*
* _.isArrayLikeObject(document.body.children);
* // => true
*
* _.isArrayLikeObject('abc');
* // => false
*
* _.isArrayLikeObject(_.noop);
* // => false
*/
function isArrayLikeObject(value) {
return isObjectLike(value) && isArrayLike(value);
}
module.exports = isArrayLikeObject;
isError检查异常
isError(value)
Checks if
value
is anError
,EvalError
,RangeError
,ReferenceError
,SyntaxError
,TypeError
, orURIError
object.检查 value 是否是 Error, EvalError, RangeError, ReferenceError,SyntaxError, TypeError, 或者 URIError对象。
参数
- value any 待检查的值
返回
boolean
如果 value 是一个错误(Error)对象,那么返回 true,否则返回 false。
源码
源码中涉及的函数
var baseGetTag = require('./_baseGetTag'),
isObjectLike = require('./isObjectLike'),
isPlainObject = require('./isPlainObject');
/** `Object#toString` result references. */
var domExcTag = '[object DOMException]',
errorTag = '[object Error]';
/**
* Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`,
* `SyntaxError`, `TypeError`, or `URIError` object.
*
* @static
* @memberOf _
* @since 3.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an error object, else `false`.
* @example
*
* _.isError(new Error);
* // => true
*
* _.isError(Error);
* // => false
*/
function isError(value) {
if (!isObjectLike(value)) {
return false;
}
var tag = baseGetTag(value);
return tag == errorTag || tag == domExcTag ||
(typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value));
}
module.exports = isError;
isFunction检查函数
Checks if
value
is classified as aFunction
object.检查’ value ‘是否被分类为’ Function '对象。
参数
- value 待检查值
返回
Boolean
是否是函数方法
源码
/**
* Checks if `value` is classified as a `Function` object.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a function, else `false`.
* @example
*
* _.isFunction(_);
* // => true
*
* _.isFunction(/abc/);
* // => false
*/
function isFunction(value) {
if (!isObject(value)) {
return false;
}
// The use of `Object#toString` avoids issues with the `typeof` operator
// in Safari 9 which returns 'object' for typed arrays and other constructors.
var tag = baseGetTag(value);
return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
}
isLength检查有效长度
Checks if
value
is a valid array-like length.检查’ value '是否是一个有效的类数组长度。
参数
- value 需要检查的值
返回
Boolean
是否可能是数组长度
源码
源码中涉及的常量
/**
* Checks if `value` is a valid array-like length.
*
* **Note:** This method is loosely based on
* [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
* @example
*
* _.isLength(3);
* // => true
*
* _.isLength(Number.MIN_VALUE);
* // => false
*
* _.isLength(Infinity);
* // => false
*
* _.isLength('3');
* // => false
*/
function isLength(value) {
return typeof value == 'number' &&
value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
}
isNaN检查NaN
isNaN(value)
Checks if
value
isNaN
.Note: This method is based on
Number.isNaN
and is not the same as globalisNaN
which returnstrue
forundefined
and other non-number values.检查
value
是否是NaN
。注意: 这个方法基于
Number.isNaN
,和全局的isNaN
不同之处在于,全局的isNaN
对 于undefined
和其他非数字的值返回true
。
参数
- value any 待检测的值
返回
boolean
如果 value
是一个 NaN
,那么返回 true
,否则返回 false
。
源码
源码中涉及的函数
var isNumber = require('./isNumber');
/**
* Checks if `value` is `NaN`.
*
* **Note:** This method is based on
* [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as
* global [`isNaN`](https://mdn.io/isNaN) which returns `true` for
* `undefined` and other non-number values.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
* @example
*
* _.isNaN(NaN);
* // => true
*
* _.isNaN(new Number(NaN));
* // => true
*
* isNaN(undefined);
* // => true
*
* _.isNaN(undefined);
* // => false
*/
function isNaN(value) {
// An `NaN` primitive is the only value that is not equal to itself.
// Perform the `toStringTag` check first to avoid errors with some
// ActiveX objects in IE.
return isNumber(value) && value != +value;
}
module.exports = isNaN;
isNil检查null或者undefined
isNil(value)
Checks if
value
isnull
orundefined
.检查
value
是否是null
或者undefined
。
参数
- value any 待检测的值
返回
boolean
如果value是null或者undefined,返回true,否则返回false
示例
示例1
console.log(isNil(undefined))//true
console.log(isNil(null))//true
源码
/**
* Checks if `value` is `null` or `undefined`.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is nullish, else `false`.
* @example
*
* _.isNil(null);
* // => true
*
* _.isNil(void 0);
* // => true
*
* _.isNil(NaN);
* // => false
*/
function isNil(value) {
return value == null;
}
module.exports = isNil;
isNull检查null
isNull(value)
Checks if
value
isnull
.检查
value
alue 是否是null
。
参数
- value any 待检测的值
返回
boolean
如果value是null,返回true,否则返回false
源码
/**
* Checks if `value` is `null`.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is `null`, else `false`.
* @example
*
* _.isNull(null);
* // => true
*
* _.isNull(void 0);
* // => false
*/
function isNull(value) {
return value === null;
}
module.exports = isNull;
isNumber检查number
isNumber(value)
Checks if
value
is classified as aNumber
primitive or object.Note: To exclude
Infinity
,-Infinity
, andNaN
, which are
classified as numbers, use the_.isFinite
method.检查
value
是否是原始Number
数值型 或者 对象。注意: 要排除 Infinity, -Infinity, 以及 NaN 数值类型,用_.isFinite 方法。
参数
- value any 待检测的值
返回
boolean
如果 value
为一个数值,那么返回 true
,否则返回 false
。
源码
源码中涉及的函数
var baseGetTag = require('./_baseGetTag'),
isObjectLike = require('./isObjectLike');
/** `Object#toString` result references. */
var numberTag = '[object Number]';
/**
* Checks if `value` is classified as a `Number` primitive or object.
*
* **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are
* classified as numbers, use the `_.isFinite` method.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a number, else `false`.
* @example
*
* _.isNumber(3);
* // => true
*
* _.isNumber(Number.MIN_VALUE);
* // => true
*
* _.isNumber(Infinity);
* // => true
*
* _.isNumber('3');
* // => false
*/
function isNumber(value) {
return typeof value == 'number' ||
(isObjectLike(value) && baseGetTag(value) == numberTag);
}
module.exports = isNumber;
isObject检查对象
isObject(value)
Checks if
value
is the language type ofObject
. (e.g. arrays, functions, objects, regexes,new Number(0)
, andnew String('')
)检查 value 是否为 Object 的language type。 (例如: arrays, functions, objects, regexes,new Number(0), 以及 new String(’’))
参数
- value any 待检查的值
返回
boolean
如果 value 为一个对象,那么返回 true,否则返回 false。
源码
/**
* Checks if `value` is the
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @static
* @memberOf _
* @since 0.1.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
* @example
*
* _.isObject({});
* // => true
*
* _.isObject([1, 2, 3]);
* // => true
*
* _.isObject(_.noop);
* // => true
*
* _.isObject(null);
* // => false
*/
function isObject(value) {
var type = typeof value;
return value != null && (type == 'object' || type == 'function');
}
module.exports = isObject;
isObjectLike检查类对象
isObjectLike(value)
Checks if
value
is object-like. A value is object-like if it’s notnull
and has atypeof
result of “object”.检查 value 是否是 类对象。 如果一个值是类对象,那么它不应该是 null,而且 typeof 后的结果是 “object”。
参数
- value any 待检查的值
返回
boolean
如果 value 为一个类对象,那么返回 true,否则返回 false。
源码
/**
* Checks if `value` is object-like. A value is object-like if it's not `null`
* and has a `typeof` result of "object".
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
* @example
*
* _.isObjectLike({});
* // => true
*
* _.isObjectLike([1, 2, 3]);
* // => true
*
* _.isObjectLike(_.noop);
* // => false
*
* _.isObjectLike(null);
* // => false
*/
function isObjectLike(value) {
return value != null && typeof value == 'object';
}
module.exports = isObjectLike;
isPlainObject检查普通对象
isPlainObject(value)
Checks if
value
is a plain object, that is, an object created by theObject
constructor or one with a[[Prototype]]
ofnull
.检查 value 是否是普通对象。 也就是说该对象由 Object 构造函数创建,或者 [[Prototype]] 为 null 。
参数
- value any 待检查的值
返回
boolean
如果 value
为一个普通对象,那么返回 true
,否则返回 false
。
源码
源码中涉及的函数
var baseGetTag = require('./_baseGetTag'),
getPrototype = require('./_getPrototype'),
isObjectLike = require('./isObjectLike');
/** `Object#toString` result references. */
var objectTag = '[object Object]';
/** Used for built-in method references. */
var funcProto = Function.prototype,
objectProto = Object.prototype;
/** Used to resolve the decompiled source of functions. */
var funcToString = funcProto.toString;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/** Used to infer the `Object` constructor. */
var objectCtorString = funcToString.call(Object);
/**
* Checks if `value` is a plain object, that is, an object created by the
* `Object` constructor or one with a `[[Prototype]]` of `null`.
*
* @static
* @memberOf _
* @since 0.8.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
* @example
*
* function Foo() {
* this.a = 1;
* }
*
* _.isPlainObject(new Foo);
* // => false
*
* _.isPlainObject([1, 2, 3]);
* // => false
*
* _.isPlainObject({ 'x': 0, 'y': 0 });
* // => true
*
* _.isPlainObject(Object.create(null));
* // => true
*/
function isPlainObject(value) {
if (!isObjectLike(value) || baseGetTag(value) != objectTag) {
return false;
}
var proto = getPrototype(value);
if (proto === null) {
return true;
}
var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
return typeof Ctor == 'function' && Ctor instanceof Ctor &&
funcToString.call(Ctor) == objectCtorString;
}
module.exports = isPlainObject;
isString检查字符串
isString(value)
Checks if
value
is classified as aString
primitive or object.检查
value
是否是原始字符串String
或者对象。
参数
- value any 待检查值
返回
boolean
如果 value
为一个字符串,那么返回 true
,否则返回 false
。
源码
源码中涉及的函数
var baseGetTag = require('./_baseGetTag'),
isArray = require('./isArray'),
isObjectLike = require('./isObjectLike');
/** `Object#toString` result references. */
var stringTag = '[object String]';
/**
* Checks if `value` is classified as a `String` primitive or object.
*
* @static
* @since 0.1.0
* @memberOf _
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a string, else `false`.
* @example
*
* _.isString('abc');
* // => true
*
* _.isString(1);
* // => false
*/
function isString(value) {
return typeof value == 'string' ||
(!isArray(value) && isObjectLike(value) && baseGetTag(value) == stringTag);
}
module.exports = isString;
isSymbol检查符号
Checks if
value
is classified as aSymbol
primitive or object.检查
value
是否是原始Symbol
或者对象。
参数
- value 需要检查的值
返回
Boolean
源码
/**
* Checks if `value` is classified as a `Symbol` primitive or object.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
* @example
*
* _.isSymbol(Symbol.iterator);
* // => true
*
* _.isSymbol('abc');
* // => false
*/
function isSymbol(value) {
return typeof value == 'symbol' ||
(isObjectLike(value) && baseGetTag(value) == symbolTag);
}
join数组以指定分隔符转为字符串
join(array, [separator=’,’])
Converts all elements in
array
into a string separated byseparator
.将 array 中的所有元素转换为由 separator 分隔的字符串。
参数
- array Array 待转化的字符串
- separator string 可选 分隔符 默认separator=’,’
返回
string
返回转化后的字符串
源码
/** Used for built-in method references. */
var arrayProto = Array.prototype;
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeJoin = arrayProto.join;
/**
* Converts all elements in `array` into a string separated by `separator`.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Array
* @param {Array} array The array to convert.
* @param {string} [separator=','] The element separator.
* @returns {string} Returns the joined string.
* @example
*
* _.join(['a', 'b', 'c'], '~');
* // => 'a~b~c'
*/
function join(array, separator) {
return array == null ? '' : nativeJoin.call(array, separator);
}
module.exports = join;
keyBy集合迭代生成键
keyBy(collection, [iteratee=_.identity])
Creates an object composed of keys generated from the results of running each element of
collection
thruiteratee
. The corresponding value of each key is the last element responsible for generating the key. The iteratee is invoked with one argument: (value).创建一个对象组成, key(键) 是
collection
(集合)中的每个元素经过iteratee
(迭代函数) 处理后返回的结果。 每个 key(键)对应的值是生成key(键)的最后一个元素。iteratee
(迭代函数)调用1个参数:(value)。
参数
- collection Array|Object 待操作的集合
- iteratee Array|Function|Object|string 可选 这个迭代函数用来转换key。
返回
Object
返回一个组成聚合的对象。
示例
示例1
var array = [
{ 'dir': 'left', 'code': 97 },
{ 'dir': 'right', 'code': 100 }
];
console.log(keyBy(array, 'dir'))
//{ left: { dir: 'left', code: 97 }, right: { dir: 'right', code: 100 } }
示例2
let array = [
{ key: 'a', value: 0 },
{ key: 'a', value: 1 },
{ key: 'b', value: 2 }
]
console.log(keyBy(array, 'key'))
//{ a: { key: 'a', value: 1 }, b: { key: 'b', value: 2 } }
源码
源码中涉及的函数
var baseAssignValue = require('./_baseAssignValue'),
createAggregator = require('./_createAggregator');
/**
* Creates an object composed of keys generated from the results of running
* each element of `collection` thru `iteratee`. The corresponding value of
* each key is the last element responsible for generating the key. The
* iteratee is invoked with one argument: (value).
*
* @static
* @memberOf _
* @since 4.0.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} [iteratee=_.identity] The iteratee to transform keys.
* @returns {Object} Returns the composed aggregate object.
* @example
*
* var array = [
* { 'dir': 'left', 'code': 97 },
* { 'dir': 'right', 'code': 100 }
* ];
*
* _.keyBy(array, function(o) {
* return String.fromCharCode(o.code);
* });
* // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } }
*
* _.keyBy(array, 'dir');
* // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } }
*/
var keyBy = createAggregator(function(result, value, key) {
baseAssignValue(result, key, value);
});
module.exports = keyBy;
keys对象属性名数组
keys(object)
Creates an array of the own enumerable property names of
object
.创建一个
object
的自身可枚举属性名为数组。
注意: 非对象的值会强制转换为对象。
参数
- object Object 待操作对象
返回
Array
返回由对象可枚举属性的属性名构成的数组
源码
源码中涉及的函数
var arrayLikeKeys = require('./_arrayLikeKeys'),
baseKeys = require('./_baseKeys'),
isArrayLike = require('./isArrayLike');
/**
* Creates an array of the own enumerable property names of `object`.
*
* **Note:** Non-object values are coerced to objects. See the
* [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
* for more details.
*
* @static
* @since 0.1.0
* @memberOf _
* @category Object
* @param {Object} object The object to query.
* @returns {Array} Returns the array of property names.
* @example
*
* function Foo() {
* this.a = 1;
* this.b = 2;
* }
*
* Foo.prototype.c = 3;
*
* _.keys(new Foo);
* // => ['a', 'b'] (iteration order is not guaranteed)
*
* _.keys('hi');
* // => ['0', '1']
*/
function keys(object) {
return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);
}
module.exports = keys;
last获取数组最后一个元素
last(array)
Gets the last element of
array
.获取数组最后一个元素
参数
- array Array 待处理的数组
返回
any
返回数组的最后一个元素
源码
/**
* Gets the last element of `array`.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Array
* @param {Array} array The array to query.
* @returns {*} Returns the last element of `array`.
* @example
*
* _.last([1, 2, 3]);
* // => 3
*/
function last(array) {
var length = array == null ? 0 : array.length;
return length ? array[length - 1] : undefined;
}
module.exports = last;
lastIndexOf数组倒序查询
lastIndexOf(array, value, [fromIndex=array.length-1])
This method is like
_.indexOf
except that it iterates over elements ofarray
from right to left.这个方法类似_.indexOf ,区别是它是从右到左遍历array的元素。
参数
- array Array 待查询的数组
- value any 待查询的值
- fromIndex number 可选 查询的起始位置 默认fromIndex=array.length-1
返回
number
如果存在匹配的元素,返回这个元素的索引,否则返回-1
源码
源码中涉及的方法
var baseFindIndex = require('./_baseFindIndex'),
baseIsNaN = require('./_baseIsNaN'),
strictLastIndexOf = require('./_strictLastIndexOf'),
toInteger = require('./toInteger');
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max,
nativeMin = Math.min;
/**
* This method is like `_.indexOf` except that it iterates over elements of
* `array` from right to left.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Array
* @param {Array} array The array to inspect.
* @param {*} value The value to search for.
* @param {number} [fromIndex=array.length-1] The index to search from.
* @returns {number} Returns the index of the matched value, else `-1`.
* @example
*
* _.lastIndexOf([1, 2, 1, 2], 2);
* // => 3
*
* // Search from the `fromIndex`.
* _.lastIndexOf([1, 2, 1, 2], 2, 2);
* // => 1
*/
function lastIndexOf(array, value, fromIndex) {
var length = array == null ? 0 : array.length;
if (!length) {
return -1;
}
var index = length;
if (fromIndex !== undefined) {
index = toInteger(fromIndex);
index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1);
}
return value === value
? strictLastIndexOf(array, value, index)
: baseFindIndex(array, baseIsNaN, index, true);
}
module.exports = lastIndexOf;
map集合遍历
map(collection, [iteratee=_.identity])
Creates an array of values by running each element in
collection
thruiteratee
. The iteratee is invoked with three arguments: (value, index|key, collection).创建一个数组, value(值) 是
iteratee
(迭代函数)遍历collection
(集合)中的每个元素后返回的结果。 iteratee(迭代函数)调用3个参数:(value, index|key, collection).
参数
- collection Array|Object 待遍历的集合
- iteratee Array|Function|Object|string 可选 迭代器 每次遍历调用
返回
Array
返回新的处理后的数组
源码
源码中涉及的函数
var arrayMap = require('./_arrayMap'),
baseIteratee = require('./_baseIteratee'),
baseMap = require('./_baseMap'),
isArray = require('./isArray');
/**
* Creates an array of values by running each element in `collection` thru
* `iteratee`. The iteratee is invoked with three arguments:
* (value, index|key, collection).
*
* Many lodash methods are guarded to work as iteratees for methods like
* `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
*
* The guarded methods are:
* `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
* `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
* `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
* `template`, `trim`, `trimEnd`, `trimStart`, and `words`
*
* @static
* @memberOf _
* @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @returns {Array} Returns the new mapped array.
* @example
*
* function square(n) {
* return n * n;
* }
*
* _.map([4, 8], square);
* // => [16, 64]
*
* _.map({ 'a': 4, 'b': 8 }, square);
* // => [16, 64] (iteration order is not guaranteed)
*
* var users = [
* { 'user': 'barney' },
* { 'user': 'fred' }
* ];
*
* // The `_.property` iteratee shorthand.
* _.map(users, 'user');
* // => ['barney', 'fred']
*/
function map(collection, iteratee) {
var func = isArray(collection) ? arrayMap : baseMap;
return func(collection, baseIteratee(iteratee, 3));
}
module.exports = map;
maen数组均值计算
mean(array)
Computes the mean of the values in
array
.计算
array
的平均值。
参数
- array Array 待计算的数组
返回
number
返回计算后的均值
示例
示例1
console.log(mean([4, 2, 8, 6]))//5
示例2
console.log(mean([true, false]))//0.5
示例3
console.log(mean(['a', 'b']))//NaN
源码
源码中涉及的函数
- baseMean
-
[identity](#identity返回首个提供的参数)
var baseMean = require('./_baseMean'),
identity = require('./identity');
/**
* Computes the mean of the values in `array`.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Math
* @param {Array} array The array to iterate over.
* @returns {number} Returns the mean.
* @example
*
* _.mean([4, 2, 8, 6]);
* // => 5
*/
function mean(array) {
return baseMean(array, identity);
}
module.exports = mean;
memoize缓存化函数
memoize(func, [resolver])
Creates a function that memoizes the result of
func
. Ifresolver
is provided, it determines the cache key for storing the result based on the arguments provided to the memoized function. By default, the first argument provided to the memoized function is used as the map cache key. Thefunc
is invoked with thethis
binding of the memoized function.Note: The cache is exposed as the
cache
property on the memoized function. Its creation may be customized by replacing the_.memoize.Cache
constructor with one whose instances implement theMap
method interface ofclear
,delete
,get
,has
, andset
.创建一个会缓存
func
结果的函数。 如果提供了resolver
,就用 resolver 的返回值作为 key 缓存函数的结果。 默认情况下用第一个参数作为缓存的 key。func
在调用时this
会绑定在缓存函数上。注意: 缓存会暴露在缓存函数的
cache
上。 它是可以定制的,只要替换了_.memoize.Cache
构造函数,或实现了Map
的delete
,get
,has
, 和set
方法。
参数
- func Function 需要缓存化的函数
- resolver Function 可选 这个函数的返回值作为缓存的 key
返回
Function
返回缓存化后的函数
示例
示例1
var func = memoize(function (s) {
console.log('s', s)
return s
}, function (...rest) {
console.log('rest', rest)
return 'a'
})
var res = ['a', 'b', 'c'].map(val => func(val))
console.log(func.cache.get('a'))//a
//rest [ 'a' ]
//s a
//rest [ 'b' ]
//rest [ 'c' ]
//a
示例2
var func = memoize(function (s) {
return s
})
var res = ['a', 'b', 'c'].map(val => func(val))
console.log(func.cache.get('a'))//a
console.log(func.cache.get('b'))//b
console.log(func.cache.get('c'))//c
解析
var MapCache = require('./_MapCache');
/** Error message constants. */
var FUNC_ERROR_TEXT = 'Expected a function';
function memoize(func, resolver) {
if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
throw new TypeError(FUNC_ERROR_TEXT);
}
var memoized = function() {
var args = arguments,//获取参数
//获取缓存键,如果没有resolver则以第一个参数作为键
key = resolver ? resolver.apply(this, args) : args[0],
cache = memoized.cache;
//如果缓存中已经有了结果,直接返回缓存的结果
if (cache.has(key)) {
return cache.get(key);
}
//调用func获取结果并缓存值
var result = func.apply(this, args);
memoized.cache = cache.set(key, result) || cache;
return result;
};
memoized.cache = new (memoize.Cache || MapCache);
return memoized;
}
// Expose `MapCache`.
memoize.Cache = MapCache;
module.exports = memoize;
源码
源码中涉及到的函数
var MapCache = require('./_MapCache');
/** Error message constants. */
var FUNC_ERROR_TEXT = 'Expected a function';
/**
* Creates a function that memoizes the result of `func`. If `resolver` is
* provided, it determines the cache key for storing the result based on the
* arguments provided to the memoized function. By default, the first argument
* provided to the memoized function is used as the map cache key. The `func`
* is invoked with the `this` binding of the memoized function.
*
* **Note:** The cache is exposed as the `cache` property on the memoized
* function. Its creation may be customized by replacing the `_.memoize.Cache`
* constructor with one whose instances implement the
* [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
* method interface of `clear`, `delete`, `get`, `has`, and `set`.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Function
* @param {Function} func The function to have its output memoized.
* @param {Function} [resolver] The function to resolve the cache key.
* @returns {Function} Returns the new memoized function.
* @example
*
* 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;
*/
function memoize(func, resolver) {
if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
throw new TypeError(FUNC_ERROR_TEXT);
}
var memoized = function() {
var args = arguments,
key = resolver ? resolver.apply(this, args) : args[0],
cache = memoized.cache;
if (cache.has(key)) {
return cache.get(key);
}
var result = func.apply(this, args);
memoized.cache = cache.set(key, result) || cache;
return result;
};
memoized.cache = new (memoize.Cache || MapCache);
return memoized;
}
// Expose `MapCache`.
memoize.Cache = MapCache;
module.exports = memoize;
multiply两数相乘
multiply(multiplier, multiplicand)
Multiply two numbers.
两数相乘
参数
- multiplier number 乘数
- multiplicand number 被乘数
返回
number
计算后的结果
源码
源码中涉及的函数
var createMathOperation = require('./_createMathOperation');
/**
* Multiply two numbers.
*
* @static
* @memberOf _
* @since 4.7.0
* @category Math
* @param {number} multiplier The first number in a multiplication.
* @param {number} multiplicand The second number in a multiplication.
* @returns {number} Returns the product.
* @example
*
* _.multiply(6, 4);
* // => 24
*/
var multiply = createMathOperation(function(multiplier, multiplicand) {
return multiplier * multiplicand;
}, 1);
module.exports = multiply;
negate创建取反函数
negate(predicate)
Creates a function that negates the result of the predicate
func
. Thefunc
predicate is invoked with thethis
binding and arguments of the created function.创建一个针对断言函数
func
结果取反的函数。func
断言函数被调用的时候,this
绑定到创建的函数,并传入对应参数。
参数
- predicate Function 需要对结果取反的函数
返回
Function
返回一个新的取反函数。
示例
示例1
function isEven(n) {
return n % 2 == 0;
}
console.log([1, 2, 3, 4, 5, 6].filter(negate(isEven)))
//[ 1, 3, 5 ]
源码
/** Error message constants. */
var FUNC_ERROR_TEXT = 'Expected a function';
/**
* Creates a function that negates the result of the predicate `func`. The
* `func` predicate is invoked with the `this` binding and arguments of the
* created function.
*
* @static
* @memberOf _
* @since 3.0.0
* @category Function
* @param {Function} predicate The predicate to negate.
* @returns {Function} Returns the new negated function.
* @example
*
* function isEven(n) {
* return n % 2 == 0;
* }
*
* _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
* // => [1, 3, 5]
*/
function negate(predicate) {
if (typeof predicate != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
return function() {
var args = arguments;
switch (args.length) {
case 0: return !predicate.call(this);
case 1: return !predicate.call(this, args[0]);
case 2: return !predicate.call(this, args[0], args[1]);
case 3: return !predicate.call(this, args[0], args[1], args[2]);
}
return !predicate.apply(this, args);
};
}
module.exports = negate;
now获取Unix纪元至今毫秒数
now()
Gets the timestamp of the number of milliseconds that have elapsed since the Unix epoch (1 January 1970 00:00:00 UTC).
获得 Unix 纪元 (1 January
1970 00
:00:00 UTC) 直到现在的毫秒数。
返回
number
返回时间戳。
源码
var root = require('./_root');
/**
* Gets the timestamp of the number of milliseconds that have elapsed since
* the Unix epoch (1 January 1970 00:00:00 UTC).
*
* @static
* @memberOf _
* @since 2.4.0
* @category Date
* @returns {number} Returns the timestamp.
* @example
*
* _.defer(function(stamp) {
* console.log(_.now() - stamp);
* }, _.now());
* // => Logs the number of milliseconds it took for the deferred invocation.
*/
var now = function () {
return root.Date.now();
};
module.exports = now;
nth数组获取指定索引元素
nth(array, [n=0])
Gets the element at index
n
ofarray
. Ifn
is negative, the nth element from the end is returned.获取array数组的第n个元素。如果n为负数,则返回从数组结尾开始的第n个元素。
参数
- array Array 待处理数组
- n number 可选 索引 默认n=0
返回
any
返回数组的第n个元素
源码
源码中涉及的方法
var baseNth = require('./_baseNth'),
toInteger = require('./toInteger');
/**
* Gets the element at index `n` of `array`. If `n` is negative, the nth
* element from the end is returned.
*
* @static
* @memberOf _
* @since 4.11.0
* @category Array
* @param {Array} array The array to query.
* @param {number} [n=0] The index of the element to return.
* @returns {*} Returns the nth element of `array`.
* @example
*
* var array = ['a', 'b', 'c', 'd'];
*
* _.nth(array, 1);
* // => 'b'
*
* _.nth(array, -2);
* // => 'c';
*/
function nth(array, n) {
return (array && array.length) ? baseNth(array, toInteger(n)) : undefined;
}
module.exports = nth;
omit 对象属性过滤
omit(object,[props])
参数
- object 源对象,等待过滤的对象
- [props] 属性字符串数组,需要被过滤掉的属性
返回
object
返回一个源对象的浅拷贝,内部属性不包含[props]中的属性
示例1——基础用法
import { omit } from 'lodash';
const obj_1 = {
a: '1',
b: 2,
c: true,
d: {
a: 2
},
}
const obj_2 = omit(obj_1, ['a', 'b'])
console.log('obj_2', obj_2)
//obj_2 { c: true, d: { a: 2 } }
console.log('obj_1', obj_1)
//obj_1 { a: '1', b: 2, c: true, d: { a: 2 } }
obj_1.d.a = 3
obj_1.c = true
console.log('obj_2', obj_2)
//obj_2 { c: true, d: { a: 3 } }
由示例1可以看出使用omit过滤生成的对象是原来对象的一个浅拷贝
示例2——使用JSON完成深拷贝
import { omit } from 'lodash';
const obj_1 = {
a: '1',
b: 2,
c: true,
d: {
a: 2
},
}
const obj_2 = JSON.parse(JSON.stringify(omit(obj_1, ['a', 'b'])))
console.log('obj_2', obj_2)
//obj_2 { c: true, d: { a: 2 } }
console.log('obj_1', obj_1)
//obj_1 { a: '1', b: 2, c: true, d: { a: 2 } }
obj_1.d.a = 3
obj_1.c = false
console.log('obj_2', obj_2)
obj_2 { c: true, d: { a: 2 } }
在omit外包装上JSON的两个转化方法,可以深拷贝一份omit过滤后的对象
示例3——带路径的属性
首先是一个普通用例
import { omit } from 'lodash';
const obj_1 = {
a: '1',
b: 2,
c: true,
d: {
a: 2,
b: 3,
c: {
a: 5,
}
},
}
const obj_2 = omit(obj_1, ['a', 'b'])
console.log('obj_2', obj_2)
//obj_2 { c: true, d: { a: 2, b: 3, c: { a: 5 } } }
console.log('obj_1', obj_1)
//obj_1 { a: '1', b: 2, c: true, d: { a: 2, b: 3, c: { a: 5 } } }
obj_1.d.b = 4
obj_1.d.c.a = 4
console.log('obj_2', obj_2)
//obj_2 { c: true, d: { a: 2, b: 4, c: { a: 4 } } }
从打印结果中发现,obj_2.d是obj_1.d的引用
再来下一个例子
import { omit } from 'lodash';
const obj_1 = {
a: '1',
b: 2,
c: true,
d: {
a: 2,
b: 3,
c: {
a: 5,
}
},
}
const obj_2 = omit(obj_1, ['a', 'b', 'd.a'])
console.log('obj_2', obj_2)
//obj_2 { c: true, d: { b: 3, c: { a: 5 } } }
console.log('obj_1', obj_1)
//obj_1 { a: '1', b: 2, c: true, d: { a: 2, b: 3, c: { a: 5 } } }
obj_1.d.b = 4
obj_1.d.c.a = 4
console.log('obj_2', obj_2)
//obj_2 { c: true, d: { b: 3, c: { a: 5 } } }
首先,使用 . 是可以过滤子对象的属性的
但是当我们修改
obj_1.d.b = 4
obj_1.d.c.a = 4
发现obj_2相对应的属性值并没有被修改,显然此时obj_2.d已经是不同于obj_1.d新对象了,并且其子对象也并不是与obj_1指向同一个地址,此时obj_2的子对象d是obj_1.d的深拷贝
解析
/**
* The opposite of `_.pick`; this method creates an object composed of the
* own and inherited enumerable property paths of `object` that are not omitted.
*
* **Note:** This method is considerably slower than `_.pick`.
*
* @static
* @since 0.1.0
* @memberOf _
* @category Object
* @param {Object} object The source object.
* @param {...(string|string[])} [paths] The property paths to omit.
* @returns {Object} Returns the new object.
* @example
*
* var object = { 'a': 1, 'b': '2', 'c': 3 };
*
* _.omit(object, ['a', 'c']);
* // => { 'b': '2' }
*/
var omit = flatRest(function (object, paths) {
var result = {};
if (object == null) {
return result;
}
var isDeep = false;
paths = arrayMap(paths, function (path) {
path = castPath(path, object);
//如果path是属性路径如a.b 形式,则isDeep=true
console.log('path', path)
//path [ 'a' ]
//path [ 'b' ]
//path [ 'd', 'a' ]
isDeep || (isDeep = path.length > 1);
return path;
});
console.log('paths', paths)
//paths [ [ 'a' ], [ 'b' ], [ 'd', 'a' ] ]
console.log('isDeep', isDeep)
//isDeep true
//拷贝object对象的所有键值
copyObject(object, getAllKeysIn(object), result);
if (isDeep) {
result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
}
console.log('result', result)
//result { a: '1', b: 2, c: true, d: { a: 2, b: 3, c: { a: 5 } } }
var length = paths.length;
while (length--) {
baseUnset(result, paths[length]);
console.log(`result——${length}`, result)
//result——2 { a: '1', b: 2, c: true, d: { b: 3, c: { a: 5 } } }
//result——1 { a: '1', c: true, d: { b: 3, c: { a: 5 } } }
//result——0 { c: true, d: { b: 3, c: { a: 5 } } }
}
return result;
});
const obj_1 = {
a: '1',
b: 2,
c: true,
d: {
a: 2,
b: 3,
c: {
a: 5,
}
},
}
const obj_2 = omit(obj_1, ['a', 'b', 'd.a'])
console.log('obj_2', obj_2)
//obj_2 { c: true, d: { b: 3, c: { a: 5 } } }
源码
源码内涉及的方法
var arrayMap = require('./_arrayMap'),
baseClone = require('./_baseClone'),
baseUnset = require('./_baseUnset'),
castPath = require('./_castPath'),
copyObject = require('./_copyObject'),
customOmitClone = require('./_customOmitClone'),
flatRest = require('./_flatRest'),
getAllKeysIn = require('./_getAllKeysIn');
/** Used to compose bitmasks for cloning. */
var CLONE_DEEP_FLAG = 1,
CLONE_FLAT_FLAG = 2,
CLONE_SYMBOLS_FLAG = 4;
/**
* The opposite of `_.pick`; this method creates an object composed of the
* own and inherited enumerable property paths of `object` that are not omitted.
*
* **Note:** This method is considerably slower than `_.pick`.
*
* @static
* @since 0.1.0
* @memberOf _
* @category Object
* @param {Object} object The source object.
* @param {...(string|string[])} [paths] The property paths to omit.
* @returns {Object} Returns the new object.
* @example
*
* var object = { 'a': 1, 'b': '2', 'c': 3 };
*
* _.omit(object, ['a', 'c']);
* // => { 'b': '2' }
*/
var omit = flatRest(function(object, paths) {
var result = {};
if (object == null) {
return result;
}
var isDeep = false;
paths = arrayMap(paths, function(path) {
path = castPath(path, object);
isDeep || (isDeep = path.length > 1);
return path;
});
copyObject(object, getAllKeysIn(object), result);
if (isDeep) {
result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
}
var length = paths.length;
while (length--) {
baseUnset(result, paths[length]);
}
return result;
});
module.exports = omit;
once函数单次调用
once(func)
Creates a function that is restricted to invoking
func
once. Repeat calls to the function return the value of the first invocation. Thefunc
is invoked with thethis
binding and arguments of the created function.创建一个只能调用
func
一次的函数。 重复调用返回第一次调用的结果。func
调用时,this
绑定到创建的函数,并传入对应参数。
参数
- func Function 待包装的函数
返回
Function
返回新的只能调用一次的函数
示例
示例1
var count = 0
const func = once((x) => {
count++
console.log('count=', count)
console.log('x*x=', x * x)
return x * x
})
let arr = [func(2), func(3), func(4)]
console.log(arr)
//count= 1
//x*x= 4
//[ 4, 4, 4 ]
源码
源码中涉及到的函数
var before = require('./before');
/**
* Creates a function that is restricted to invoking `func` once. Repeat calls
* to the function return the value of the first invocation. The `func` is
* invoked with the `this` binding and arguments of the created function.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Function
* @param {Function} func The function to restrict.
* @returns {Function} Returns the new restricted function.
* @example
*
* var initialize = _.once(createApplication);
* initialize();
* initialize();
* // => `createApplication` is invoked once
*/
function once(func) {
return before(2, func);
}
module.exports = once;
orderBy集合迭代结果指定排序
orderBy(collection, [iteratees=[_.identity]], [orders])
This method is like
_.sortBy
except that it allows specifying the sort orders of the iteratees to sort by. Iforders
is unspecified, all values are sorted in ascending order. Otherwise, specify an order of “desc” for descending or “asc” for ascending sort order of corresponding values.此方法类似于_.sortBy,除了它允许指定 iteratee(迭代函数)结果如何排序。 如果没指定 orders(排序),所有值以升序排序。 否则,指定为"desc" 降序,或者指定为 “asc” 升序,排序对应值。
参数
- collection Array|Object 待操作的集合
- iteratees Array[]|Function[]|Object[]|string[] 可选 排序的迭代函数 迭代器集合
- orders string[] 迭代函数的排序顺序
返回
Array
返回排序后的新数组
示例
示例1
按“用户”升序排序,按“年龄”降序排序
var users = [
{ 'user': 'fred', 'age': 48 },
{ 'user': 'barney', 'age': 34 },
{ 'user': 'fred', 'age': 40 },
{ 'user': 'barney', 'age': 36 }
];
console.log(orderBy(users, ['user', 'age'], ['asc', 'desc']))
// [
// { user: 'barney', age: 36 },
// { user: 'barney', age: 34 },
// { user: 'fred', age: 48 },
// { user: 'fred', age: 40 }
// ]
源码
源码中涉及的函数
var baseOrderBy = require('./_baseOrderBy'),
isArray = require('./isArray');
/**
* This method is like `_.sortBy` except that it allows specifying the sort
* orders of the iteratees to sort by. If `orders` is unspecified, all values
* are sorted in ascending order. Otherwise, specify an order of "desc" for
* descending or "asc" for ascending sort order of corresponding values.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]]
* The iteratees to sort by.
* @param {string[]} [orders] The sort orders of `iteratees`.
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`.
* @returns {Array} Returns the new sorted array.
* @example
*
* 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]]
*/
function orderBy(collection, iteratees, orders, guard) {
if (collection == null) {
return [];
}
if (!isArray(iteratees)) {
iteratees = iteratees == null ? [] : [iteratees];
}
orders = guard ? undefined : orders;
if (!isArray(orders)) {
orders = orders == null ? [] : [orders];
}
return baseOrderBy(collection, iteratees, orders);
}
module.exports = orderBy;
overArgs函数参数覆写
overArgs(func, [transforms=[_.identity]])
Creates a function that invokes
func
with its arguments transformed.创建一个函数,调用
func
时参数为相对应的transforms
的返回值。
参数
- func Function 待包装函数
- transforms Array[Function]|Function 可选 对func的参数进行处理的函数,返回值将作为func的新参数
返回
Function
返回新的函数
示例
示例1
var func = overArgs(function (x, y) {
return [x, y];
}, [(n) => n * n, (n) => 3 * n]);
console.log(func(9, 3));
//[81, 9]
示例2
var func = overArgs(function (x, y) {
return [x, y];
}, [(n) => n * n]);
console.log(func(9, 3));
// [81, 3]
示例3
var func = overArgs(function (x, y) {
return [x, y];
}, (n) => n * n);
console.log(func(9, 3));
// [81, 3]
解析
var apply = require('./_apply'),
arrayMap = require('./_arrayMap'),
baseFlatten = require('./_baseFlatten'),
baseIteratee = require('./_baseIteratee'),
baseRest = require('./_baseRest'),
baseUnary = require('./_baseUnary'),
castRest = require('./_castRest'),
isArray = require('./isArray');
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMin = Math.min;
var overArgs = castRest(function(func, transforms) {
//如果transforms长度为一,并且第一项为数组(castRest转换后的参数会外加一个[]),调用arrayMap对transforms
//中的每一个参数处理函数执行baseUnary(创建只接受一个参数的函数)
transforms = (transforms.length == 1 && isArray(transforms[0]))
? arrayMap(transforms[0], baseUnary(baseIteratee))
: arrayMap(baseFlatten(transforms, 1), baseUnary(baseIteratee));
//获取transform长度
var funcsLength = transforms.length;
return baseRest(function(args) {
var index = -1,
//取处理函数数量与func参数数量的较小值,一个参数对应一个参数处理函数
length = nativeMin(args.length, funcsLength);
//对参数进行处理
while (++index < length) {
args[index] = transforms[index].call(this, args[index]);
}
return apply(func, this, args);
});
});
module.exports = overArgs;
源码
源码中涉及到的函数
var apply = require('./_apply'),
arrayMap = require('./_arrayMap'),
baseFlatten = require('./_baseFlatten'),
baseIteratee = require('./_baseIteratee'),
baseRest = require('./_baseRest'),
baseUnary = require('./_baseUnary'),
castRest = require('./_castRest'),
isArray = require('./isArray');
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMin = Math.min;
/**
* Creates a function that invokes `func` with its arguments transformed.
*
* @static
* @since 4.0.0
* @memberOf _
* @category Function
* @param {Function} func The function to wrap.
* @param {...(Function|Function[])} [transforms=[_.identity]]
* The argument transforms.
* @returns {Function} Returns the new function.
* @example
*
* 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]
*/
var overArgs = castRest(function(func, transforms) {
transforms = (transforms.length == 1 && isArray(transforms[0]))
? arrayMap(transforms[0], baseUnary(baseIteratee))
: arrayMap(baseFlatten(transforms, 1), baseUnary(baseIteratee));
var funcsLength = transforms.length;
return baseRest(function(args) {
var index = -1,
length = nativeMin(args.length, funcsLength);
while (++index < length) {
args[index] = transforms[index].call(this, args[index]);
}
return apply(func, this, args);
});
});
module.exports = overArgs;
partial预设参数
partial(func, [partials])
Creates a function that invokes
func
withpartials
prepended to the arguments it receives. This method is like_.bind
except it does not alter thethis
binding.The
_.partial.placeholder
value, which defaults to_
in monolithic builds, may be used as a placeholder for partially applied arguments.Note: This method doesn’t set the “length” property of partially applied functions.
创建一个函数。 该函数调用 func,并传入预设的 partials 参数。 这个方法类似_.bind,除了它不会绑定 this。
这个 _.partial.placeholder 的值,默认是以 _ 作为附加部分参数的占位符。
注意: 这个方法不会设置 “length” 到函数上。
参数
- func Function 需要预设参数的函数
- partials …any 可选 预设的参数
返回
Function
返回有预设参数的函数
源码
源码中涉及到的函数
var baseRest = require('./_baseRest'),
createWrap = require('./_createWrap'),
getHolder = require('./_getHolder'),
replaceHolders = require('./_replaceHolders');
/** Used to compose bitmasks for function metadata. */
var WRAP_PARTIAL_FLAG = 32;
/**
* Creates a function that invokes `func` with `partials` prepended to the
* arguments it receives. This method is like `_.bind` except it does **not**
* alter the `this` binding.
*
* The `_.partial.placeholder` value, which defaults to `_` in monolithic
* builds, may be used as a placeholder for partially applied arguments.
*
* **Note:** This method doesn't set the "length" property of partially
* applied functions.
*
* @static
* @memberOf _
* @since 0.2.0
* @category Function
* @param {Function} func The function to partially apply arguments to.
* @param {...*} [partials] The arguments to be partially applied.
* @returns {Function} Returns the new partially applied function.
* @example
*
* 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'
*/
var partial = baseRest(function(func, partials) {
var holders = replaceHolders(partials, getHolder(partial));
return createWrap(func, WRAP_PARTIAL_FLAG, undefined, partials, holders);
});
// Assign default placeholders.
partial.placeholder = {};
module.exports = partial;
partialRight附加预设参数
partialRight(func, [partials])
This method is like
_.partial
except that partially applied arguments are appended to the arguments it receives.The
_.partialRight.placeholder
value, which defaults to_
in monolithic builds, may be used as a placeholder for partially applied arguments.Note: This method doesn’t set the “length” property of partially applied functions.
这个函数类似_.partial,除了预设参数被附加到接受参数的后面。
这个 _.partialRight.placeholder 的值,默认是以 _ 作为附加部分参数的占位符。
注意: 这个方法不会设置 “length” 到函数上。
参数
- func Function 待预设参数的函数
- partials …any 可选 预设的参数
返回
Function
返回预设参数的函数。
源码
源码中涉及到的函数
var baseRest = require('./_baseRest'),
createWrap = require('./_createWrap'),
getHolder = require('./_getHolder'),
replaceHolders = require('./_replaceHolders');
/** Used to compose bitmasks for function metadata. */
var WRAP_PARTIAL_RIGHT_FLAG = 64;
/**
* This method is like `_.partial` except that partially applied arguments
* are appended to the arguments it receives.
*
* The `_.partialRight.placeholder` value, which defaults to `_` in monolithic
* builds, may be used as a placeholder for partially applied arguments.
*
* **Note:** This method doesn't set the "length" property of partially
* applied functions.
*
* @static
* @memberOf _
* @since 1.0.0
* @category Function
* @param {Function} func The function to partially apply arguments to.
* @param {...*} [partials] The arguments to be partially applied.
* @returns {Function} Returns the new partially applied function.
* @example
*
* function greet(greeting, name) {
* return greeting + ' ' + name;
* }
*
* var greetFred = _.partialRight(greet, 'fred');
* greetFred('hi');
* // => 'hi fred'
*
* // Partially applied with placeholders.
* var sayHelloTo = _.partialRight(greet, 'hello', _);
* sayHelloTo('fred');
* // => 'hello fred'
*/
var partialRight = baseRest(function(func, partials) {
var holders = replaceHolders(partials, getHolder(partialRight));
return createWrap(func, WRAP_PARTIAL_RIGHT_FLAG, undefined, partials, holders);
});
// Assign default placeholders.
partialRight.placeholder = {};
module.exports = partialRight;
partition集合分组
partition(collection, [predicate=_.identity])
Creates an array of elements split into two groups, the first of which contains elements
predicate
returns truthy for, the second of which contains elementspredicate
returns falsey for. The predicate is invoked with one argument: (value).
参数
- collection Array|Object 待分组的集合
- predicate Array|Function|Object|string 可选 断言 迭代器 每次迭代调用的函数
返回
Array
返回分组后的数组
源码
源码中涉及的函数
var createAggregator = require('./_createAggregator');
/**
* Creates an array of elements split into two groups, the first of which
* contains elements `predicate` returns truthy for, the second of which
* contains elements `predicate` returns falsey for. The predicate is
* invoked with one argument: (value).
*
* @static
* @memberOf _
* @since 3.0.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} [predicate=_.identity] The function invoked per iteration.
* @returns {Array} Returns the array of grouped elements.
* @example
*
* var users = [
* { 'user': 'barney', 'age': 36, 'active': false },
* { 'user': 'fred', 'age': 40, 'active': true },
* { 'user': 'pebbles', 'age': 1, 'active': false }
* ];
*
* _.partition(users, function(o) { return o.active; });
* // => objects for [['fred'], ['barney', 'pebbles']]
*
* // The `_.matches` iteratee shorthand.
* _.partition(users, { 'age': 1, 'active': false });
* // => objects for [['pebbles'], ['barney', 'fred']]
*
* // The `_.matchesProperty` iteratee shorthand.
* _.partition(users, ['active', false]);
* // => objects for [['barney', 'pebbles'], ['fred']]
*
* // The `_.property` iteratee shorthand.
* _.partition(users, 'active');
* // => objects for [['fred'], ['barney', 'pebbles']]
*/
var partition = createAggregator(function(result, value, key) {
//key为true,存到result[0] key的值由断言产生,true|false
result[key ? 0 : 1].push(value);
}, function() { return [[], []]; });
module.exports = partition;
pull数组移除指定值
pull(array, [values])
Removes all given values from
array
usingSameValueZero
for equality comparisons.移除数组array中所有和给定值相等的元素,使用SameValueZero 进行全等比较。
注意:pull类函数是直接在原数组上进行操作的
参数
- array Array 待操作数组
- [values] rest any 可选 待移除的值
返回
Array
处理后的数组
示例
示例1
let array = ['a', 'b', 'c', 'a', 'b', 'c'];
res = pull(array, 'a', 'c')
console.log('array', array)//array [ 'b', 'b' ]
console.log('res', res)//res [ 'b', 'b' ]
源码
源码中涉及的方法
var baseRest = require('./_baseRest'),
pullAll = require('./pullAll');
/**
* Removes all given values from `array` using
* [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
* for equality comparisons.
*
* **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove`
* to remove elements from an array by predicate.
*
* @static
* @memberOf _
* @since 2.0.0
* @category Array
* @param {Array} array The array to modify.
* @param {...*} [values] The values to remove.
* @returns {Array} Returns `array`.
* @example
*
* var array = ['a', 'b', 'c', 'a', 'b', 'c'];
*
* _.pull(array, 'a', 'c');
* console.log(array);
* // => ['b', 'b']
*/
var pull = baseRest(pullAll);
module.exports = pull;
pullAll数组移除指定列表中的值
pullAll(array, values)
This method is like
_.pull
except that it accepts an array of values to remove.这个方法类似_.pull,区别是这个方法接收一个要移除值的数组。
注意:pull类函数是直接在原数组上进行操作的
参数
- array Array 待处理数组
- values Array 要移除值的数组
返回
Array
处理后的数组
示例
示例1
console.log(pullAll(['a', 'b', 'c', 'a', 'b', 'c'], ['a', 'c']))//[ 'b', 'b' ]
源码
源码中涉及的方法
- basePullAll pullAll实现的基础方法
var basePullAll = require('./_basePullAll');
/**
* This method is like `_.pull` except that it accepts an array of values to remove.
*
* **Note:** Unlike `_.difference`, this method mutates `array`.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Array
* @param {Array} array The array to modify.
* @param {Array} values The values to remove.
* @returns {Array} Returns `array`.
* @example
*
* var array = ['a', 'b', 'c', 'a', 'b', 'c'];
*
* _.pullAll(array, ['a', 'c']);
* console.log(array);
* // => ['b', 'b']
*/
function pullAll(array, values) {
return (array && array.length && values && values.length)
? basePullAll(array, values)
: array;
}
module.exports = pullAll;
pullAllBy数组迭代移除
pullAllBy(array, values, [iteratee=_.identity])
This method is like
_.pullAll
except that it acceptsiteratee
which is invoked for each element ofarray
andvalues
to generate the criterion by which they’re compared. The iteratee is invoked with one argument: (value).这个方法类似于_.pullAll ,区别是这个方法接受一个 iteratee(迭代函数) 调用 array 和 values的每个值以产生一个值,通过产生的值进行了比较。iteratee 会传入一个参数: (value)。
注意:pull类函数是直接在原数组上进行操作的
参数
- array Array 待处理的数组
- values Array 要移除的值
- iteratee Array|Function|Object|string 可选 迭代器
返回
Array
返回修改后的数组
源码
源码中涉及的方法
var baseIteratee = require('./_baseIteratee'),
basePullAll = require('./_basePullAll');
/**
* This method is like `_.pullAll` except that it accepts `iteratee` which is
* invoked for each element of `array` and `values` to generate the criterion
* by which they're compared. The iteratee is invoked with one argument: (value).
*
* **Note:** Unlike `_.differenceBy`, this method mutates `array`.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Array
* @param {Array} array The array to modify.
* @param {Array} values The values to remove.
* @param {Function} [iteratee=_.identity] The iteratee invoked per element.
* @returns {Array} Returns `array`.
* @example
*
* var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }];
*
* _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x');
* console.log(array);
* // => [{ 'x': 2 }]
*/
function pullAllBy(array, values, iteratee) {
return (array && array.length && values && values.length)
? basePullAll(array, values, baseIteratee(iteratee, 2))
: array;
}
module.exports = pullAllBy;
pullAllWith数组条件移除
pullAllWith(array, values, [comparator])
This method is like
_.pullAll
except that it acceptscomparator
which is invoked to compare elements ofarray
tovalues
. The comparator is invoked with two arguments: (arrVal, othVal).这个方法类似于_.pullAll,区别是这个方法接受 comparator 调用array中的元素和values比较。comparator 会传入两个参数:(arrVal, othVal)。
注意:pull类函数是直接在原数组上进行操作的
参数
- array Array 待处理数组
- values Array 要移除的值
- comparator Function 可选 比较器
返回
Array
返回修改后的数组
源码
源码中涉及的方法
var basePullAll = require('./_basePullAll');
/**
* This method is like `_.pullAll` except that it accepts `comparator` which
* is invoked to compare elements of `array` to `values`. The comparator is
* invoked with two arguments: (arrVal, othVal).
*
* **Note:** Unlike `_.differenceWith`, this method mutates `array`.
*
* @static
* @memberOf _
* @since 4.6.0
* @category Array
* @param {Array} array The array to modify.
* @param {Array} values The values to remove.
* @param {Function} [comparator] The comparator invoked per element.
* @returns {Array} Returns `array`.
* @example
*
* 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 }]
*/
function pullAllWith(array, values, comparator) {
return (array && array.length && values && values.length)
? basePullAll(array, values, undefined, comparator)
: array;
}
module.exports = pullAllWith;
pullAt数组移除对应索引元素
pullAt(array, [indexes])
Removes elements from
array
corresponding toindexes
and returns an array of removed elements.根据索引
indexes
,移除array
中对应的元素,并返回被移除元素的数组。
注意:pull类函数是直接在原数组上进行操作的
参数
- array Array 待操作的数组
- indexs …(number|number[]) 可选 待移除的值的索引
返回
Array
返回移除元素组成的新数组。
示例
示例1
let array = [5, 10, 15, 20];
let evens = pullAt(array, 1, 3);
console.log(array)//[ 5, 15 ]
console.log(evens)//[ 10, 20 ]
解析
var arrayMap = require('./_arrayMap'),
baseAt = require('./_baseAt'),
basePullAt = require('./_basePullAt'),
compareAscending = require('./_compareAscending'),
flatRest = require('./_flatRest'),
isIndex = require('./_isIndex');
/**
* Removes elements from `array` corresponding to `indexes` and returns an
* array of removed elements.
*
* **Note:** Unlike `_.at`, this method mutates `array`.
*
* @static
* @memberOf _
* @since 3.0.0
* @category Array
* @param {Array} array The array to modify.
* @param {...(number|number[])} [indexes] The indexes of elements to remove.
* @returns {Array} Returns the new array of removed elements.
* @example
*
* var array = ['a', 'b', 'c', 'd'];
* var pulled = _.pullAt(array, [1, 3]);
*
* console.log(array);
* // => ['a', 'c']
*
* console.log(pulled);
* // => ['b', 'd']
*/
var pullAt = flatRest(function(array, indexes) {
var length = array == null ? 0 : array.length,
//从数组中提取对应坐标的元素作为返回的结果
result = baseAt(array, indexes);
//先使用arrayMap对indexe索引数组的每一项进行处理,检查是否为索引,然后对处理后的结果进行升序排序
//最后调用basePullAt移除数组中指定索引的值
basePullAt(array, arrayMap(indexes, function(index) {
return isIndex(index, length) ? +index : index;
}).sort(compareAscending));
return result;
});
module.exports = pullAt;
源码
源码中涉及的函数
var arrayMap = require('./_arrayMap'),
baseAt = require('./_baseAt'),
basePullAt = require('./_basePullAt'),
compareAscending = require('./_compareAscending'),
flatRest = require('./_flatRest'),
isIndex = require('./_isIndex');
/**
* Removes elements from `array` corresponding to `indexes` and returns an
* array of removed elements.
*
* **Note:** Unlike `_.at`, this method mutates `array`.
*
* @static
* @memberOf _
* @since 3.0.0
* @category Array
* @param {Array} array The array to modify.
* @param {...(number|number[])} [indexes] The indexes of elements to remove.
* @returns {Array} Returns the new array of removed elements.
* @example
*
* var array = ['a', 'b', 'c', 'd'];
* var pulled = _.pullAt(array, [1, 3]);
*
* console.log(array);
* // => ['a', 'c']
*
* console.log(pulled);
* // => ['b', 'd']
*/
var pullAt = flatRest(function(array, indexes) {
var length = array == null ? 0 : array.length,
result = baseAt(array, indexes);
basePullAt(array, arrayMap(indexes, function(index) {
return isIndex(index, length) ? +index : index;
}).sort(compareAscending));
return result;
});
module.exports = pullAt;
rearg函数指定参数调用
rearg(func, indexes)
Creates a function that invokes
func
with arguments arranged according to the specifiedindexes
where the argument value at the first index is provided as the first argument, the argument value at the second index is provided as the second argument, and so on.创建一个函数,调用
func
时,根据指定的indexes
调整对应位置参数。其中第一个索引值是对应第一个参数,第二个索引值是作为第二个参数,依此类推。
参数
- func Function 待包装的函数
- indexes …(number|number[]) 排列参数的位置
返回
Function
返回新的函数。
示例
示例1
索引2表示函数rearged将使用第三个实参a作为第一个参数,索引0表示rearged函数将使用第1个参数b作为第二个参数
var rearged = rearg(function (a, b, c) {
return [a, b, c];
}, [2, 0, 1]);
console.log(rearged('b', 'c', 'a'))
//[ 'a', 'b', 'c' ]
源码
源码中涉及到的函数
var createWrap = require('./_createWrap'),
flatRest = require('./_flatRest');
/** Used to compose bitmasks for function metadata. */
var WRAP_REARG_FLAG = 256;
/**
* Creates a function that invokes `func` with arguments arranged according
* to the specified `indexes` where the argument value at the first index is
* provided as the first argument, the argument value at the second index is
* provided as the second argument, and so on.
*
* @static
* @memberOf _
* @since 3.0.0
* @category Function
* @param {Function} func The function to rearrange arguments for.
* @param {...(number|number[])} indexes The arranged argument indexes.
* @returns {Function} Returns the new function.
* @example
*
* var rearged = _.rearg(function(a, b, c) {
* return [a, b, c];
* }, [2, 0, 1]);
*
* rearged('b', 'c', 'a')
* // => ['a', 'b', 'c']
*/
var rearg = flatRest(function(func, indexes) {
return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes);
});
module.exports = rearg;
reduce集合累计操作
reduce(collection, [iteratee=_.identity], [accumulator])
Reduces
collection
to a value which is the accumulated result of running each element incollection
thruiteratee
, where each successive invocation is supplied the return value of the previous. Ifaccumulator
is not given, the first element ofcollection
is used as the initial value. The iteratee is invoked with four arguments: (accumulator, value, index|key, collection).Many lodash methods are guarded to work as iteratees for methods like
_.reduce
,_.reduceRight
, and_.transform
.The guarded methods are:
assign
,defaults
,defaultsDeep
,includes
,merge
,orderBy
, andsortBy
压缩 collection(集合)为一个值,通过 iteratee(迭代函数)遍历 collection(集合)中的每个元素,每次返回的值会作为下一次迭代使用(注:作为iteratee(迭代函数)的第一个参数使用)。 如果没有提供 accumulator,则 collection(集合)中的第一个元素作为初始值。(注:accumulator参数在第一次迭代的时候作为iteratee(迭代函数)第一个参数使用。) iteratee 调用4个参数:
(accumulator, value, index|key, collection).lodash 中有许多方法是防止作为其他方法的迭代函数(注:即不能作为iteratee参数传递给其他方法),例如:.reduce,.reduceRight, 和_.transform。
受保护的方法有(注:即这些方法不能使用_.reduce,.reduceRight, 和.transform作为 iteratee 迭代函数参数):
assign, defaults, defaultsDeep, includes, merge, orderBy, 和 sortBy
参数
- collection Array|Object 待操作的集合
- iteratee Function 可选 每次迭代调用的函数 调用4个参数(accumulator, value, index|key, collection)
- accumulator any 可选 初始值
返回
any
返回累加后的值
源码
源码中涉及的函数
var arrayReduce = require('./_arrayReduce'),
baseEach = require('./_baseEach'),
baseIteratee = require('./_baseIteratee'),
baseReduce = require('./_baseReduce'),
isArray = require('./isArray');
/**
* Reduces `collection` to a value which is the accumulated result of running
* each element in `collection` thru `iteratee`, where each successive
* invocation is supplied the return value of the previous. If `accumulator`
* is not given, the first element of `collection` is used as the initial
* value. The iteratee is invoked with four arguments:
* (accumulator, value, index|key, collection).
*
* Many lodash methods are guarded to work as iteratees for methods like
* `_.reduce`, `_.reduceRight`, and `_.transform`.
*
* The guarded methods are:
* `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
* and `sortBy`
*
* @static
* @memberOf _
* @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @param {*} [accumulator] The initial value.
* @returns {*} Returns the accumulated value.
* @see _.reduceRight
* @example
*
* _.reduce([1, 2], function(sum, n) {
* return sum + n;
* }, 0);
* // => 3
*
* _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
* (result[value] || (result[value] = [])).push(key);
* return result;
* }, {});
* // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
*/
function reduce(collection, iteratee, accumulator) {
var func = isArray(collection) ? arrayReduce : baseReduce,
initAccum = arguments.length < 3;
//如果参数数量小于3,即accumulator未传入,initAccum为true,使用集合第一个元素作为初始值
return func(collection, baseIteratee(iteratee, 4), accumulator, initAccum, baseEach);
}
module.exports = reduce;
reduceRight集合倒序累计操作
reduceRight(collection, [iteratee=_.identity], [accumulator])
This method is like
_.reduce
except that it iterates over elements ofcollection
from right to left.这个方法类似_.reduce ,除了它是从右到左遍历collection(集合)中的元素的。
参数
- collection Array|Object 待操作的集合
- iteratee Function 可选 迭代器 每次迭代调用的函数。
- accumulator any 可选 初始值
返回
any
返回累加后的值
源码
源码中涉及的函数
var arrayReduceRight = require('./_arrayReduceRight'),
baseEachRight = require('./_baseEachRight'),
baseIteratee = require('./_baseIteratee'),
baseReduce = require('./_baseReduce'),
isArray = require('./isArray');
/**
* This method is like `_.reduce` except that it iterates over elements of
* `collection` from right to left.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} [iteratee=_.identity] The function invoked per iteration.
* @param {*} [accumulator] The initial value.
* @returns {*} Returns the accumulated value.
* @see _.reduce
* @example
*
* var array = [[0, 1], [2, 3], [4, 5]];
*
* _.reduceRight(array, function(flattened, other) {
* return flattened.concat(other);
* }, []);
* // => [4, 5, 2, 3, 0, 1]
*/
function reduceRight(collection, iteratee, accumulator) {
var func = isArray(collection) ? arrayReduceRight : baseReduce,
initAccum = arguments.length < 3;
return func(collection, baseIteratee(iteratee, 4), accumulator, initAccum, baseEachRight);
}
module.exports = reduceRight;
reject集合filter反向过滤
reject(collection, [predicate=_.identity])
The opposite of
_.filter
; this method returns the elements ofcollection
thatpredicate
does not return truthy for._.filter的反向方法;此方法 返回 predicate(断言函数) 不 返回 truthy(真值)的collection(集合)元素(注释:非真)。
参数
- collection Array|Object 待过滤的集合
- predicate Array|Function|Object|string 可选 断言
返回
Array
返回过滤后的新数组
源码
源码中涉及到的函数
var arrayFilter = require('./_arrayFilter'),
baseFilter = require('./_baseFilter'),
baseIteratee = require('./_baseIteratee'),
isArray = require('./isArray'),
negate = require('./negate');
/**
* The opposite of `_.filter`; this method returns the elements of `collection`
* that `predicate` does **not** return truthy for.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} [predicate=_.identity] The function invoked per iteration.
* @returns {Array} Returns the new filtered array.
* @see _.filter
* @example
*
* var users = [
* { 'user': 'barney', 'age': 36, 'active': false },
* { 'user': 'fred', 'age': 40, 'active': true }
* ];
*
* _.reject(users, function(o) { return !o.active; });
* // => objects for ['fred']
*
* // The `_.matches` iteratee shorthand.
* _.reject(users, { 'age': 40, 'active': true });
* // => objects for ['barney']
*
* // The `_.matchesProperty` iteratee shorthand.
* _.reject(users, ['active', false]);
* // => objects for ['fred']
*
* // The `_.property` iteratee shorthand.
* _.reject(users, 'active');
* // => objects for ['barney']
*/
function reject(collection, predicate) {
var func = isArray(collection) ? arrayFilter : baseFilter;
return func(collection, negate(baseIteratee(predicate, 3)));
}
module.exports = reject;
remove数组条件移除所有值
remove(array, [predicate=_.identity])
Removes all elements from
array
thatpredicate
returns truthy for and returns an array of the removed elements. The predicate is invoked with three arguments: (value, index, array).移除数组中predicate(断言)返回为真值的所有元素,并返回移除元素组成的数组。predicate(断言) 会传入3个参数: (value, index, array)。
注意:remove会改变原数组,因为remove的基础实现与pullAt的基础实现函数一致
参数
- array Array 待操作的数组
- predicate Function 可选 断言函数
返回
Array
被移除的值组成的新数组
源码
源码中涉及的函数
var baseIteratee = require('./_baseIteratee'),
basePullAt = require('./_basePullAt');
/**
* Removes all elements from `array` that `predicate` returns truthy for
* and returns an array of the removed elements. The predicate is invoked
* with three arguments: (value, index, array).
*
* **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull`
* to pull elements from an array by value.
*
* @static
* @memberOf _
* @since 2.0.0
* @category Array
* @param {Array} array The array to modify.
* @param {Function} [predicate=_.identity] The function invoked per iteration.
* @returns {Array} Returns the new array of removed elements.
* @example
*
* 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]
*/
function remove(array, predicate) {
var result = [];
if (!(array && array.length)) {
return result;
}
var index = -1,
indexes = [],
length = array.length;
predicate = baseIteratee(predicate, 3);
while (++index < length) {
var value = array[index];
if (predicate(value, index, array)) {
result.push(value);
indexes.push(index);
}
}
basePullAt(array, indexes);
return result;
}
module.exports = remove;
reverse数组倒置
reverse(array)
Reverses
array
so that the first element becomes the last, the second element becomes the second to last, and so on.反转array,使得第一个元素变为最后一个元素,第二个元素变为倒数第二个元素,依次类推。
注意:reverse会改变原数组,它是基于Array.prototype.reverse;
参数
- array Array 待处理的数组
返回
Array
倒置后的数组
源码
/** Used for built-in method references. */
var arrayProto = Array.prototype;
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeReverse = arrayProto.reverse;
/**
* Reverses `array` so that the first element becomes the last, the second
* element becomes the second to last, and so on.
*
* **Note:** This method mutates `array` and is based on
* [`Array#reverse`](https://mdn.io/Array/reverse).
*
* @static
* @memberOf _
* @since 4.0.0
* @category Array
* @param {Array} array The array to modify.
* @returns {Array} Returns `array`.
* @example
*
* var array = [1, 2, 3];
*
* _.reverse(array);
* // => [3, 2, 1]
*
* console.log(array);
* // => [3, 2, 1]
*/
function reverse(array) {
return array == null ? array : nativeReverse.call(array);
}
module.exports = reverse;
round四舍五入
round(number, [precision=0])
Computes
number
rounded toprecision
.根据 precision(精度) 四舍五入 number。
参数
- number number 待舍入的值
- precision number 可选 精度,保留的小数位数 默认precision=0
返回
number
舍入后的值
源码
源码中涉及到的函数
var createRound = require('./_createRound');
/**
* Computes `number` rounded to `precision`.
*
* @static
* @memberOf _
* @since 3.10.0
* @category Math
* @param {number} number The number to round.
* @param {number} [precision=0] The precision to round to.
* @returns {number} Returns the rounded number.
* @example
*
* _.round(4.006);
* // => 4
*
* _.round(4.006, 2);
* // => 4.01
*
* _.round(4060, -2);
* // => 4100
*/
var round = createRound('round');
module.exports = round;
sample获取集合中一个随机元素
sample(collection)
Gets a random element from
collection
.从collection(集合)中获得一个随机元素。
参数
- collection Array|Object 待取值的集合
返回
any
返回一个随机元素
源码
源码中涉及到的函数
var arraySample = require('./_arraySample'),
baseSample = require('./_baseSample'),
isArray = require('./isArray');
/**
* Gets a random element from `collection`.
*
* @static
* @memberOf _
* @since 2.0.0
* @category Collection
* @param {Array|Object} collection The collection to sample.
* @returns {*} Returns the random element.
* @example
*
* _.sample([1, 2, 3, 4]);
* // => 2
*/
function sample(collection) {
var func = isArray(collection) ? arraySample : baseSample;
return func(collection);
}
module.exports = sample;
sampleSize获取集合中n个随机元素
sampleSize(collection, [n=1])
Gets
n
random elements at unique keys fromcollection
up to the size ofcollection
.从
collection
(集合)中获得n
个随机元素。
参数
- collection Array|Object 待获取的集合
- n number 可选 获取的元素个数 默认n=1
- guard Object 可选 是否可以作为遍历参数被_.map之类的方法调用.
返回
Array
返回随机元素组成的数组
源码
源码中涉及的函数
var arraySampleSize = require('./_arraySampleSize'),
baseSampleSize = require('./_baseSampleSize'),
isArray = require('./isArray'),
isIterateeCall = require('./_isIterateeCall'),
toInteger = require('./toInteger');
/**
* Gets `n` random elements at unique keys from `collection` up to the
* size of `collection`.
*
* @static
* @memberOf _
* @since 4.0.0
* @category Collection
* @param {Array|Object} collection The collection to sample.
* @param {number} [n=1] The number of elements to sample.
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
* @returns {Array} Returns the random elements.
* @example
*
* _.sampleSize([1, 2, 3], 2);
* // => [3, 1]
*
* _.sampleSize([1, 2, 3], 4);
* // => [2, 3, 1]
*/
function sampleSize(collection, n, guard) {
if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) {
n = 1;
} else {
n = toInteger(n);
}
var func = isArray(collection) ? arraySampleSize : baseSampleSize;
return func(collection, n);
}
module.exports = sampleSize;
shuffle集合随机重组为数组
shuffle(collection)
Creates an array of shuffled values, using a version of the Fisher-Yates shuffle
创建一个被打乱值的集合。 使用Fisher-Yates shuffle 版本。
简单概述:
进行size次循环,每次循环,在index到lastIndex位置上的值中随机娶一个放到index位置上,可以得出其放置值x的几率为
P(0号位不放x) · P(1号位不放x) · … · P(index位放x)=
\frac{size-1}{size}*\frac{size-2}{size-1}*\frac{size-3}{size-2}*...*\frac{size-(index-1)-1}{size-(index-1)}*\frac{1}{size-index}=\frac{1}{size}
这是洗牌算法的等概率
参数
- collection Array|Object 要打乱的集合
返回
Array
返回打乱的新数组。
示例
示例1
console.log(shuffle({
a: 0, b: 1, c: 2, d: 3, e: 4
}))//[ 0, 2, 4, 1, 3 ]
源码
源码中涉及到的函数
- arrayShuffle
- baseShuffle
-
[isArray](#isArray检查数组)
var arrayShuffle = require('./_arrayShuffle'),
baseShuffle = require('./_baseShuffle'),
isArray = require('./isArray');
/**
* Creates an array of shuffled values, using a version of the
* [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle).
*
* @static
* @memberOf _
* @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to shuffle.
* @returns {Array} Returns the new shuffled array.
* @example
*
* _.shuffle([1, 2, 3, 4]);
* // => [4, 1, 3, 2]
*/
function shuffle(collection) {
var func = isArray(collection) ? arrayShuffle : baseShuffle;
return func(collection);
}
module.exports = shuffle;
size获取集合长度
size(collection)
Gets the size of
collection
by returning its length for array-like values or the number of own enumerable string keyed properties for objects.返回
collection
(集合)的长度,如果集合是类数组或字符串,返回其 length ;如果集合是对象,返回其可枚举属性的个数。
参数
- collection Array|Object 待操作的集合
返回
number
返回集合的长度
源码
源码中涉及到的函数
var baseKeys = require('./_baseKeys'),
getTag = require('./_getTag'),//获取数据的类型
isArrayLike = require('./isArrayLike'),
isString = require('./isString'),
stringSize = require('./_stringSize');
/** `Object#toString` result references. */
var mapTag = '[object Map]',
setTag = '[object Set]';
/**
* Gets the size of `collection` by returning its length for array-like
* values or the number of own enumerable string keyed properties for objects.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Collection
* @param {Array|Object|string} collection The collection to inspect.
* @returns {number} Returns the collection size.
* @example
*
* _.size([1, 2, 3]);
* // => 3
*
* _.size({ 'a': 1, 'b': 2 });
* // => 2
*
* _.size('pebbles');
* // => 7
*/
function size(collection) {
if (collection == null) {
return 0;
}
if (isArrayLike(collection)) {
return isString(collection) ? stringSize(collection) : collection.length;
}
var tag = getTag(collection);
if (tag == mapTag || tag == setTag) {
return collection.size;
}
return baseKeys(collection).length;
}
module.exports = size;
slice数组截取
slice(array, [start=0], [end=array.length])
Creates a slice of
array
fromstart
up to, but not including,end
.裁剪数组array,从 start 位置开始到end结束,但不包括 end 本身的位置。
Note: 这个方法用于代替Array.slice 来确保数组正确返回。
参数
- array Array 待裁剪的数组
- start number 可选 裁剪的开始位置 默认start=0
- end number 可选 裁剪的结束位置 默认end=array.length
返回
Array
返回 数组array 裁剪部分的新数组。
示例
示例1
基础用法
let a = [0, 1, 2, 3, 4, 5, 6]
let b = slice(a, 2, 4)
console.log(a)//[0, 1, 2, 3, 4, 5, 6]
console.log(b)//[ 2, 3 ]
源码
源码中涉及的函数
var baseSlice = require('./_baseSlice'),
isIterateeCall = require('./_isIterateeCall'),
toInteger = require('./toInteger');
/**
* Creates a slice of `array` from `start` up to, but not including, `end`.
*
* **Note:** This method is used instead of
* [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are
* returned.
*
* @static
* @memberOf _
* @since 3.0.0
* @category Array
* @param {Array} array The array to slice.
* @param {number} [start=0] The start position.
* @param {number} [end=array.length] The end position.
* @returns {Array} Returns the slice of `array`.
*/
function slice(array, start, end) {
var length = array == null ? 0 : array.length;
if (!length) {
return [];
}
if (end && typeof end != 'number' && isIterateeCall(array, start, end)) {
start = 0;
end = length;
}
else {
start = start == null ? 0 : toInteger(start);
end = end === undefined ? length : toInteger(end);
}
return baseSlice(array, start, end);
}
module.exports = slice;
some集合元素存在鉴定
some(collection, [predicate=_.identity])
Checks if
predicate
returns truthy for any element ofcollection
. Iteration is stopped oncepredicate
returns truthy. The predicate is invoked with three arguments: (value, index|key, collection).通过
predicate
(断言函数) 检查collection
(集合)中的元素是否存在 任意 truthy(真值)的元素,一旦predicate
(断言函数) 返回 truthy(真值),遍历就停止。 predicate 调用3个参数:(value, index|key, collection)。
参数
- collection Array|Object 待操作的集合
- predicate Array|Function|Object|string 可选 断言
- guard Object 可选 迭代守卫
返回
boolean
如果存在元素经 predicate 检查为 truthy(真值),返回 true
,否则返回 false
。
示例
示例1
console.log(some([1, 2, 3, 4, 5, 6], (n) => n * n == 9))//true
源码
源码中涉及到的函数
- arraySome
- baseSome
- baseIteratee
- isIterateeCall
-
[isArray](#isArray检查数组)
var arraySome = require('./_arraySome'),
baseIteratee = require('./_baseIteratee'),
baseSome = require('./_baseSome'),
isArray = require('./isArray'),
isIterateeCall = require('./_isIterateeCall');
/**
* Checks if `predicate` returns truthy for **any** element of `collection`.
* Iteration is stopped once `predicate` returns truthy. The predicate is
* invoked with three arguments: (value, index|key, collection).
*
* @static
* @memberOf _
* @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {Function} [predicate=_.identity] The function invoked per iteration.
* @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`.
* @returns {boolean} Returns `true` if any element passes the predicate check,
* else `false`.
* @example
*
* _.some([null, 0, 'yes', false], Boolean);
* // => true
*
* var users = [
* { 'user': 'barney', 'active': true },
* { 'user': 'fred', 'active': false }
* ];
*
* // The `_.matches` iteratee shorthand.
* _.some(users, { 'user': 'barney', 'active': false });
* // => false
*
* // The `_.matchesProperty` iteratee shorthand.
* _.some(users, ['active', false]);
* // => true
*
* // The `_.property` iteratee shorthand.
* _.some(users, 'active');
* // => true
*/
function some(collection, predicate, guard) {
var func = isArray(collection) ? arraySome : baseSome;
if (guard && isIterateeCall(collection, predicate, guard)) {
predicate = undefined;
}
return func(collection, baseIteratee(predicate, 3));
}
module.exports = some;
sortBy集合迭代升序
sortBy(collection, [iteratees=[_.identity]])
Creates an array of elements, sorted in ascending order by the results of running each element in a collection thru each iteratee. This method performs a stable sort, that is, it preserves the original sort order of equal elements. The iteratees are invoked with one argument: (value).
创建一个元素数组。 以 iteratee 处理的结果升序排序。 这个方法执行稳定排序,也就是说相同元素会保持原始排序。 iteratees 调用1个参数: (value)。
参数
- collection Array|Object 待操作的集合
- iteratees …(Array|Array[]|Function|Function[]|Object|Object[]|string|string[]) 可选 rest 决定排序
返回
Array
返回排序后的数组
示例
示例1
先根据user值升序,再根据匿名函数的处理结果升序
var users = [
{ 'user': 'fred', 'age': 48 },
{ 'user': 'barney', 'age': 36 },
{ 'user': 'fred', 'age': 30 },
{ 'user': 'barney', 'age': 34 }
];
console.log(sortBy(users, 'user', function (o) {
return Math.round(o.age);
}))
// [
// { user: 'barney', age: 34 },
// { user: 'barney', age: 36 },
// { user: 'fred', age: 30 },
// { user: 'fred', age: 48 }
// ]
解析
var baseFlatten = require('./_baseFlatten'),
baseOrderBy = require('./_baseOrderBy'),
baseRest = require('./_baseRest'),
isIterateeCall = require('./_isIterateeCall');
/**
* Creates an array of elements, sorted in ascending order by the results of
* running each element in a collection thru each iteratee. This method
* performs a stable sort, that is, it preserves the original sort order of
* equal elements. The iteratees are invoked with one argument: (value).
*
* @static
* @memberOf _
* @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {...(Function|Function[])} [iteratees=[_.identity]]
* The iteratees to sort by.
* @returns {Array} Returns the new sorted array.
* @example
*
* var users = [
* { 'user': 'fred', 'age': 48 },
* { 'user': 'barney', 'age': 36 },
* { 'user': 'fred', 'age': 30 },
* { 'user': 'barney', 'age': 34 }
* ];
*
* _.sortBy(users, [function(o) { return o.user; }]);
* // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]]
*
* _.sortBy(users, ['user', 'age']);
* // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]]
*/
var sortBy = baseRest(function (collection, iteratees) {
if (collection == null) {
return [];
}
var length = iteratees.length;
console.log('iteratees1', iteratees)
//iteratees1 [ 'user', [Function (anonymous)] ]
//如果是遍历器的参数,则遍历器为空
if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
iteratees = [];
}
//如果前三个用于排序的方法为遍历器的参数,指定遍历器为第一个
else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
iteratees = [iteratees[0]];
console.log('iteratees2', iteratees)
}
console.log('iteratees3', iteratees)
//iteratees3 [ 'user', [Function (anonymous)] ]
return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
});
var users = [
{ 'user': 'fred', 'age': 48 },
{ 'user': 'barney', 'age': 36 },
{ 'user': 'fred', 'age': 30 },
{ 'user': 'barney', 'age': 34 }
];
console.log(sortBy(users, 'user', function (o) {
return Math.round(o.age);
}))
// [
// { user: 'barney', age: 34 },
// { user: 'barney', age: 36 },
// { user: 'fred', age: 30 },
// { user: 'fred', age: 48 }
// ]
module.exports = sortBy;
源码
源码中涉及的函数
var baseFlatten = require('./_baseFlatten'),
baseOrderBy = require('./_baseOrderBy'),
baseRest = require('./_baseRest'),
isIterateeCall = require('./_isIterateeCall');
/**
* Creates an array of elements, sorted in ascending order by the results of
* running each element in a collection thru each iteratee. This method
* performs a stable sort, that is, it preserves the original sort order of
* equal elements. The iteratees are invoked with one argument: (value).
*
* @static
* @memberOf _
* @since 0.1.0
* @category Collection
* @param {Array|Object} collection The collection to iterate over.
* @param {...(Function|Function[])} [iteratees=[_.identity]]
* The iteratees to sort by.
* @returns {Array} Returns the new sorted array.
* @example
*
* var users = [
* { 'user': 'fred', 'age': 48 },
* { 'user': 'barney', 'age': 36 },
* { 'user': 'fred', 'age': 30 },
* { 'user': 'barney', 'age': 34 }
* ];
*
* _.sortBy(users, [function(o) { return o.user; }]);
* // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]]
*
* _.sortBy(users, ['user', 'age']);
* // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]]
*/
var sortBy = baseRest(function(collection, iteratees) {
if (collection == null) {
return [];
}
var length = iteratees.length;
if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) {
iteratees = [];
} else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) {
iteratees = [iteratees[0]];
}
return baseOrderBy(collection, baseFlatten(iteratees, 1), []);
});
module.exports = sortBy;
sortedIndex有序数组最小插入索引
sortedIndex(array, value)
Uses a binary search to determine the lowest index at which
value
should be inserted intoarray
in order to maintain its sort order.使用二进制的方式检索来决定
value
值 应该插入到数组中 尽可能小的索引位置,以保证array
的排序。
参数
- array Array 待检查的有序数组
- value any 待评估的值
返回
number
应该在数组中插入的最小索引位置坐标
示例
示例1
console.log(sortedIndex([30, 50], 40))//1
示例2
console.log(sortedIndex(['aabee', 'aadee'], 'aacee'))//1
源码
源码中涉及的函数
var baseSortedIndex = require('./_baseSortedIndex');
/**
* Uses a binary search to determine the lowest index at which `value`
* should be inserted into `array` in order to maintain its sort order.
*
* @static
* @memberOf _
* @since 0.1.0
* @category Array
* @param {Array} array The sorted array to inspect.
* @param {*} value The value to evaluate.
* @returns {number} Returns the index at which `value` should be inserted
* into `array`.
* @example
*
* _.sortedIndex([30, 50], 40);
* // => 1
*/
function sortedIndex(array, value) {
return baseSortedIndex(array, value);
}
module.exports = sortedIndex;
sortedIndexBy有序数组迭代最小插入索引
sortedIndexBy(array, value, [iteratee=_.identity])
This method is like
_.sortedIndex
except that it acceptsiteratee
which is invoked forvalue
and each element ofarray
to compute their sort ranking. The iteratee is invoked with one argument: (value).这个方法类似_.sortedIndex ,除了它接受一个 iteratee (迭代函数),调用每一个数组(array)元素,返回结果和value 值比较来计算排序。iteratee 会传入一个参数:(value)。
参数
- array Array 待检查的有序数组
- value any 待评估的值
- iteratee Function 可选 迭代器 支持简写
返回
number
应该在数组中插入的索引位置
源码
源码中涉及的函数
var baseIteratee = require('./_baseIteratee'),
baseSortedIndexBy = require('./_baseSortedIndexBy');
/**
* This method is like `_.sortedIndex` except that it accepts `iteratee`
* which is invoked for `value` and each element of `array`