携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第33天,点击查看活动详情
前言
lodash里的slice方法主要是裁剪数组array
,从 start
位置开始到end
结束,但不包括 end
本身的位置,该方法用于代替Array.prototype.slice来确保数组正确返回。
参数说明:
- 参数1:数组类型,表示要切片的数组。
- 参数2:数字类型,起始位置,默认为0。
- 参数3:数字类型,结束位置,默认为数组长度。
slice方法实现上,先判断参数数组是否为null,为null的话直接返回空数组,同时参数数组长度为0时也返回空数组。其次会调用isIterateeCall判断参数是否符合迭代调用,对于非整数的参数会调用toInteger对参数进行处理,最终会返回核心方法baseSlice的调用结果。
源码如下:
import baseSlice from './_baseSlice.js';
import isIterateeCall from './_isIterateeCall.js';
import toInteger from './toInteger.js';
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);
}
baseSlice
baseSlice方法是_.slice方法的基本实现。
源码如下:
function baseSlice(array, start, end) {
var index = -1,
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;
var result = Array(length);
while (++index < length) {
result[index] = array[index + start];
}
return result;
}
isIterateeCall
isIterateeCall方法主要是检查给定参数是否来自iteratee调用,如果参数来自iteratee调用,则返回true。
参数说明:
- 参数1:任意类型,表示潜在的迭代对象值参数。
- 参数2:任意类型,表示潜在的迭代对象索引或键参数。
- 参数3:对象类型,表示潜在的iteratee对象参数。
源码如下:
import eq from './eq.js';
import isArrayLike from './isArrayLike.js';
import isIndex from './_isIndex.js';
import isObject from './isObject.js';
function isIterateeCall(value, index, object) {
if (!isObject(object)) {
return false;
}
var type = typeof index;
if (type == 'number'
? (isArrayLike(object) && isIndex(index, object.length))
: (type == 'string' && index in object)
) {
return eq(object[index], value);
}
return false;
}
eq
eq方法是判断两个值是否相等。
源码如下:
function eq(value, other) {
return value === other || (value !== value && other !== other);
}
isIndex
isIndex方法主要是检查参数value
是否是有效的类数组索引。
源码如下:
var MAX_SAFE_INTEGER = 9007199254740991;
var reIsUint = /^(?:0|[1-9]\d*)$/;
function isIndex(value, length) {
var type = typeof value;
length = length == null ? MAX_SAFE_INTEGER : length;
return !!length &&
(type == 'number' ||
(type != 'symbol' && reIsUint.test(value))) &&
(value > -1 && value % 1 == 0 && value < length);
}
isObject
isObject方法主要通过typeof操作符判断数据是否属于对象类型。
源码如下:
function isObject(value) {
var type = typeof value;
return value != null && (type == 'object' || type == 'function');
}
isArrayLike
在《 lodash里的is系列(一) 》中我们已经了解到isArrayLike方法的实现。
小结
本篇章我们主要通过了解slice方法的实现,同时认识了其核心baseSlice内部方法以及isIterateeCall内部方法的实现。