Lodash version 4.17.20

preface

Lodash implemented a simple function called an array utility function that flattens multidimensional or embedded arrays with a number of clever tricks for reuse code, such as using an Infinity feature, That allowed flattening deep, flatten, union, and other functions to share a code

To the robustness of the code, flattenDeep will determine attribute Symbol. IsConcateSpreadable, this attribute controls whether the object can be merged, namely define call concat () function, so flattenDeep also can be used for class array object

Thought analysis

Source code analysis

1. flattenDeep

  1. Incoming parameter analysis
  • arrayTarget array, an array or array-like object that is flattened
  1. Source code analysis

Pass the array and Infinity as the flattening number

function flattenDeep(array) {
  var length = array == null ? 0 : array.length;
  return length ? baseFlatten(array, INFINITY) : [];
}
Copy the code

2. baseFlatten

  1. Incoming parameter analysis
  • arrayTarget array, an array or array-like object that is flattened
  • depthThe number of layers that are flattened, the number of layers that are recursively flattened
  • predicateDetermine whether it is feasible, defaultisFlattenableAnd determine whether it can be flattened
  • isStrictRestricted bypredicateThe value of the function, when we’re readyunionAnd then we’ll analyze it in detail
  • resultRecursive results, which can be passed through multiple recursions to form the final result
  1. Source code analysis
function baseFlatten(array, depth, predicate, isStrict, result) {
  var index = -1,
      length = array.length;
  predicate || (predicate = isFlattenable);
  result || (result = []);
  while (++index < length) {
    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{ arrayPush(result, value); }}else if (!isStrict) {
      result[result.length] = value;
    }
  }
  return result;
}
Copy the code

Initialize index and length, and the predicate function that processes value defaults to an isFlattenable

  var index = -1,
      length = array.length;
  predicate || (predicate = isFlattenable);
  result || (result = []);
Copy the code

By default, the predicate returns true and the flattener tests if the flattener is an array, an array-like object argument, Or a Symbol. IsConcatSpreadable attributes, can be flattened

// ...
while (++index < length) {
  var value = array[index];
  if (depth > 0 && predicate(value)) {
    // ...
  } else if (!isStrict) {
    result[result.length] = value;
  }
}
// ...
Copy the code

Check if depth is greater than 1. If depth is equal to 1, fill in the new array directly. If depth is greater than 1, continue recursing

// ...
if (depth > 1) {
  // Recursively flatten arrays (susceptible to call stack limits).
  baseFlatten(value, depth - 1, predicate, isStrict, result);
} else {
  arrayPush(result, value);
}
// ...
Copy the code

JS 中的 Infinity

Inifity represented the largest number value in JS, expressed as the maximum number that a number type could store 2^1024. It itself is larger than number. MAX_VALUE (represented as 1.79e+308).

Infinity plus, subtraction and multiplication of any number gives Infinity, and 1 over Inifnity gives you 0.

The operation between Infinity, plus and multiply is Infinity, and subtract is NaN

The Inifity value was changeable in early JS and has since been changed to read-only in ES5. And Infinity is Infinity and -infinity, the maximum and the minimum. The Infinity value is used as the maximum number and can be used to compare the size of an infinite number of loops without changing with the addition of the number

Both number. isFinite and isFinite can be used to determine whether they are Infinity, -infinity, or NaN. The difference is that number. isFinite does not cast the type. IsFinite is the opposite.

BigInt has no Infinity value and cannot be evaluated with it

There are several ways to get an Infinity value

Number.POSITIVE_INFINITY
Infinity
1/0
2支那1024
Math.pow(2.1024)
Copy the code

What is Infinity in JavaScript?

conclusion

A flattening array utilizes Infinity infinite recursion

Infinity is of type number, so the depth argument can not only achieve infinite recursion, but also be compatible with passing in a fixed number of flattening layers