John Abraham
John Abraham

Reputation: 18791

In lodash why are the predicate and results variables not prefixed with a var keyword?

Here is a copy of flattenDeep() in lodash, a function that will pass a multidimensional array and return a new array that has been flattened. This flattenDeep() is handled recursively.

Reading the source code I noticed that:

predicate and results do not use var behind them?

      predicate || (predicate = isFlattenable);
      result || (result = []);

Question: Why did lodash use global variables for predicate and results? Is there a reason/theory behind this?

Full src

Stripped out js:

var bigarray = [[1],[2,[3,3]],[1], 1];


/**
 * Checks if `value` is a flattenable `arguments` object or array.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
 */
function isFlattenable(value) {
  return Array.isArray(value);
}

/**
 * The base implementation of `_.flatten` with support for restricting flattening.
 *
 * @private
 * @param {Array} array The array to flatten.
 * @param {number} depth The maximum recursion depth.
 * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
 * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
 * @param {Array} [result=[]] The initial result value.
 * @returns {Array} Returns the new flattened array.
 */
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;
}


/**
 * Recursively flattens `array`.
 *
 * @static
 * @memberOf _
 * @since 3.0.0
 * @category Array
 * @param {Array} array The array to flatten.
 * @returns {Array} Returns the new flattened array.
 * @example
 *
 * _.flattenDeep([1, [2, [3, [4]], 5]]);
 * // => [1, 2, 3, 4, 5]
 */
function flattenDeep(array) {
  var length = array ? array.length : 0;
  return length ? baseFlatten(array, Infinity) : [];
}

console.log(flattenDeep(bigarray));

Upvotes: 1

Views: 235

Answers (1)

omarjmh
omarjmh

Reputation: 13886

They are not global, any parameters that are passed into a function are declared - which is what var does.

So in this part of the function:

function baseFlatten(array, depth, predicate, isStrict, result) {
  var index = -1,

All of the passed in parameters essentially already have a var in front of them, and note that index does indeed have a var, as to not become global.

Check out this quick JSBin and see the error that it notifies you of...

https://jsbin.com/kebekib/3/edit?js,console

Upvotes: 1

Related Questions