jchappytime / lodash-source-code-analyse Goto Github PK
View Code? Open in Web Editor NEWlodash源码分析
lodash源码分析
裁剪数组array,从start位置开始到end结束,但不包括end本身的位置。也就是左闭右开的形式。
这个方法可以替代数组本身的Array.slice()方法来确保数组正确返回。
【参数】
源码:
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;
}
length = start > end ? 0 : (end - start) >>> 0;
// 这里的>>>表示向右移位,>>>0的意思是无符号移位,该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被
// 丢弃,左侧用0填充。因为符号位变成了0,所以结果总是非负的。
start >>>= 0;
let index = -1;
const result = new Array(length);
while (++index < length) {
result[index] = array[index + start];
// 当index + 1的值小于数组长度时,result数组的index位置的值被赋值为array的[index+start位置的值]
}
return result;
}
创建一个具有唯一array值的数组,每个值不包含在其它给定的数组中。简单来说就是,检查第一个数组中的每个值,是否存在于第二个数组中,如果不存在则保留,存在则移除。
该方法使用SameValueZero做相等比较,结果值的顺序是由第一个数组中的顺序确定。
【参数】
源码:
function difference(array, ...values) {
return isArrayLikeObject(array)
? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
: []
}
这个函数中涉及到的isArrayLikeObject,baseDifference,baseFlatten分别如下:
【作用】这个函数是为了判断array是否为数组,保证数组长度小于最大值。
function isArrayLikeObject(value) {
return (typeof value === 'object' && value !== null) && (value != null && typeof value !== 'function' && isLength(value.length));
}
function isLength(value) {
return typeof value === 'number' &&
value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; // MAX_SAFE_INTEGER=9007199254740991
}
这个方法才是我们要研究的关键所在。
function baseDifference(array, values, iteratee, comparator) {
let includes = arrayIncludes
let isCommon = true
const result = []
const valuesLength = values.length
if (!array.length) {
return result
}
if (iteratee) {
values = map(values, (value) => iteratee(value))
}
if (comparator) {
includes = arrayIncludesWith
isCommon = false
}
else if (values.length >= LARGE_ARRAY_SIZE) {
includes = cacheHas
isCommon = false
values = new SetCache(values)
}
outer:
for (let value of array) {
const computed = iteratee == null ? value : iteratee(value)
value = (comparator || value !== 0) ? value : 0
if (isCommon && computed === computed) {
let valuesIndex = valuesLength
while (valuesIndex--) {
if (values[valuesIndex] === computed) {
continue outer
}
}
result.push(value)
}
else if (!includes(values, computed, comparator)) {
result.push(value)
}
}
return result
}
function baseFlatten(array, depth, predicate, isStrict, result) {
predicate || (predicate = isFlattenable)
result || (result = [])
if (array == null) {
return result
}
for (const value of array) {
if (depth > 0 && predicate(value)) {
if (depth > 1) {
// Recursively flatten arrays (susceptible to call stack limits).
baseFlatten(value, depth - 1, predicate, isStrict, result)
} else {
result.push(...value)
}
} else if (!isStrict) {
result[result.length] = value
}
}
return result
}
function isFlattenable(value) {
return Array.isArray(value) || isArguments(value) ||
!!(value && value[spreadableSymbol])
}
这里的isArguments()方法的代码就不再贴出来了。
将数组array拆分成多个size长度的区块,并将这些区块组成一个新的数组。如果array无法被分割成全部等长的区块,那么最后剩余的元素将组成一个区块。
【参数】
function chunk(array, size=1) {
size = Math.max(toInteger(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)); // 此处是用array的长度除以size大小,得到能划分出的每个区块的数组的长度
while (index < length) {
result[resIndex++] = this.slice(array, index, (index += size));
// 当index小于数组长度时,result数组的resIndex+1位置的值,被赋值为slice()方法分割出来的数组
}
return result;
}
这里slice()方法的源码见: slice分析
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.