lodash源码阅读(1)
2018-08-16 本文已影响33人
公子七
Array methods
1、chunk.js
/*chunk.js*/
// 功能:将数组array划分成length为size的几个子数组
/**
* chunk(['a', 'b', 'c', 'd'], 2)
* // => [['a', 'b'], ['c', 'd']]
*
* chunk(['a', 'b', 'c', 'd'], 3)
* // => [['a', 'b', 'c'], ['d']]
*/
function chunk(array, size) {
size = Math.max(size, 0)
const length = array == null ? 0 : array.length
if (!length || size < 1) {
return []
}
let index = 0
let resIndex = 0
// 要划分的数组的个数。不能整除取最大值。
const result = new Array(Math.ceil(length / size))
// 返回的子数组以数组集合的形式呈现。
while (index < length) {
result[resIndex++] = slice(array, index, (index += size))
}
return result
}
这段代码的思路是先判断子数组的个数,即结果数组的长度。
接着对每个子数赋值起始(start&end),利用slice方法将数组划分。
2、slice.js
接下来是slice方法。
slice方法:给定数组的起始位置,对其进行截取,得到新数组。
@param:array,start,end
// var array = [1, 2, 3, 4]
// _.slice(array, 2)
// => [3, 4]
function slice(array, start, end) {
// 边界情况的处理
let length = array == null ? 0 : array.length
if (!length) {
return []
}
start = start == null ? 0 : start
end = end === undefined ? length : end
// 对于起始为负的处理
if (start < 0) {
start = -start > length ? 0 : (length + start)
}
end = end > length ? length : end
if (end < 0) {
end += length
}
// >>>0的作用是将负数转换成无符号整数,此处length指代的是要截取的数组长度
length = start > end ? 0 : ((end - start) >>> 0)
start >>>= 0
let index = -1
const result = new Array(length)
while (++index < length) {
result[index] = array[index + start]
}
return result
}
slice方法中对于边界情况考虑的较为全面。涉及起点为空终点为空 / 起点>终点 / 负数的情况。在经过初始判断之后,生成新的数组,对新数组按位赋值,得到截取结果。
Tips:>>>0的意思是将负数转为无符号整数
3、compact.js
compact方法是个非常友好的函数,可以将数组里的一系列为空无意义的值过滤掉。
这些无意义的值包括:false, null, 0, "", undefined, NaN。
/* compact([0, 1, false, 2, '', 3])
* // => [1, 2, 3]
function compact(array) {
let resIndex = 0
const result = []
if (array == null) {
return result
}
// 遍历过滤
for (const value of array) {
if (value) {
result[resIndex++] = value
}
}
return result
}
其实读源码可以看出,框架对于边界情况的处理非常严格。compact的实现逻辑,是简单的对数组元素进行遍历判断,非空则赋值到新的结果数组中。