_.difference
文档注释
关联函数
源码解析
// 调用示例
difference([1,2,3,4],[2,3]) // ====> [1,4]
// 具体源码
var difference = baseRest(function(array, values) {
/*
baseRest可以理解对传值做了层处理,打印array是原值,values是在外面又套了层数组
比如传值values:[1,2] ===> 转化为[[1,2]]
*/
return isArrayLikeObject(array) // 这一步好理解,判断是否是数组结构
? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true))
: [];
});
function baseFlatten(array, depth, predicate, isStrict, result) {
var index = -1,
length = array.length;
predicate || (predicate = isFlattenable);
result || (result = []);
while (++index < length) { // 因为数据是[[1,2]]===> length = 1, 因此只循环一次就停止
var value = array[index];
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
* result: 空数组 []
* value: 为[2,3]
*/
arrayPush(result, value);
// function arrayPush(array= [], values = [2,3]) {
// var index = -1,
// length = values.length,
// offset = array.length;
// while (++index < length) {
// array[offset + index] = values[index];
// }
// return array;
// }
}
} else if (!isStrict) {
result[result.length] = value;
}
}
return result;
}
function baseDifference(array=[1,2,3,4], values = [2,3], iteratee=null, comparator=null) {
var index = -1,
includes = arrayIncludes,
isCommon = true,
length = array.length, // 4
result = [],
valuesLength = values.length; // 2
console.log(arrayIncludes)
if (!length) {
return result;
}
if (iteratee) {
values = arrayMap(values, baseUnary(iteratee));
}
if (comparator) {
includes = arrayIncludesWith;
isCommon = false;
}
else if (values.length >= LARGE_ARRAY_SIZE) {
includes = cacheHas;
isCommon = false;
values = new SetCache(values);
}
/*
*核心代码开始
*/
outer: // java用的一个方法,内部循环可以控制外部的循环
while (++index < length) {
var value = array[index],
computed = iteratee == null ? value : iteratee(value);
value = (comparator || value !== 0) ? value : 0;
if (isCommon && computed === computed) {
var valuesIndex = valuesLength;
while (valuesIndex--) {
if (values[valuesIndex] === computed) {
continue outer; // 跳到外部的循环,此处下部的push不在继续
}
}
result.push(value);
}
else if (!includes(values, computed, comparator)) {
result.push(value);
}
}
return result;
/*
*核心代码结束
*/
}
核心代码说明
看似方法很多,其他方法可理解为检验和处理数据,核心代码函数在baseDifference里面,通过控制外层循环,判断是不是需要把值push到新的数组中,找到相同的值跳出push操作,跳到在最外层重新循环