鲁迅说过:只有阅读过优秀库源码的人,才能配的上是真正的勇士。
dropRight
创建一个切片数组,去除array尾部的n个元素。(n默认值为1。)
_.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);
}
dropRight函数内部主要是使用了baseSlice进行分割函数,从代码逻辑上看dropRight的第三个参数guard,是没有任何意义的。为了确保n为正整数,还在内部调用了toInteger方法
toInteger
工具函数,转换成为正整数。
_.toInteger(3.2);
// => 3
_.toInteger(Number.MIN_VALUE);
// => 0
_.toInteger(Infinity);
// => 1.7976931348623157e+308
_.toInteger('3.2');
// => 3
function toInteger(value) {
var result = toFinite(value),
remainder = result % 1;
return result === result ? (remainder ? result - remainder : result) : 0;
}
在toInteger,引用了toFinite,主要是要处理字符串数字的情况,例如"3.2"这种情况=>3.2,然后进行取余,在这里就会涉及js中精度的问题了,因为3.2取余是等于0.20000000000000018,3.2-0.20000000000000018 = 3,这个地方就比较有趣了。
toFinite
if (!value) {
return value === 0 ? value : 0;
}
value = toNumber(value);
if (value === INFINITY || value === -INFINITY) {
var sign = (value < 0 ? -1 : 1);
return sign * MAX_INTEGER;
}
return value === value ? value : 0;
内部的toNumber,主要是把value变成数字输出,比较巧妙中使用了+“-3.2”=>3.2,隐式转换变成了number
baseSlice
let index = -1
let length = array.length
if (start < 0) {
start = -start > length ? 0 : (length + start)
}
end = end > length ? length : end
if (end < 0) {
end += length
}
length = start > end ? 0 : ((end - start) >>> 0)
start >>>= 0
const result = Array(length)
while (++index < length) {
result[index] = array[index + start]
}
return result