# lodash.js源码-flatten

2020-11-09 23:49:08 最普通的一个

## 功能

``_.flatten(array)``

``````_.flatten([1,[2,3,]])

// =< [1,2,3]``````

``````
function flatten(array){
let result = []
for(let i = 0; i< array.length; i++){

if(Array.isArray(array[i])) {
// 处理数组中的元素 ，push到result中
}else {
result.push(array[i])
}
}

return result
}
``````

## lodash源码实现

``````function flatten(array) {
var length = array == null ? 0 : array.length;
return length ? baseFlatten(array, 1) : [];
}``````

``````function flattenDepth(array, depth) {
const length = array == null ? 0 : array.length
if (!length) {
return []
}
depth = depth === undefined ? 1 : +depth
return baseFlatten(array, depth)
}

``````
``````function flattenDeep(array) {
const length = array == null ? 0 : array.length
return length ? baseFlatten(array, INFINITY) : []
}``````

`baseFlatten`正是`flatten**`方法的核心实现。

## 探秘baseFlatten

``````function baseFlatten(array, depth, predicate, isStrict, result) {
// predicate默认为isFlattenable, 传入的array如果是可以`flatten`化，返回true，
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
}``````

`predicate`默认为`isFlattenable`, 传入的array如果是可以`flatten`化，返回`true`.

``````for (const value of array) {
if (depth > 0 && predicate(value)) {
if (depth > 1) {
baseFlatten(value, depth - 1, predicate, isStrict, result)
} else {
result.push(...value)
}
} else if (!isStrict) {
result[result.length] = value
}
}``````

``depth > 0 && predicate(value)``

`flatten`来讲,`depth = 1`，当`for...of`迭代出的元素`predicate(value)`true

``````function isFlattenable(value) {
return Array.isArray(value) || isArguments(value) ||
}``````

`lodash`默认认为数组，arguments 和 `value[spreadableSymbol]``Flattenable`的。

`predicate`也可以手动传入。

`` result.push(...value)``

``result[result.length] = value``

`````` if (depth > 1) {
baseFlatten(value, depth - 1, predicate, isStrict, result)
} ``````

## 总结

`flatten`,`flattenDeep`,`flattenDepth`等方法都是通过`baseFlatten`衍生出来的。

https://segmentfault.com/a/1190000037779548