JavaScript实用库:Lodash源码数组函数解析(一) chunk、compact、concat、arrayPush、copyArray、isArray、baseFlatten

本章的内容主要是:chunk、compact、concat、arrayPush、copyArray、isArray、baseFlatten


在这里插入图片描述

Lodash是一个非常好用方便的JavaScript的工具库,使得我们对数据处理能够更加得心应手

接下来我要对Lodash的源码进行剖析学习
每天几个小方法,跟着我一起来学lodash吧


1、_.chunk(array, [size=1])
根据中文文档介绍,该函数是传入两个参数,第一个参数为数组array,第二个参数为数字size。将数组(array)拆分成多个 size 长度的区块,并将这些区块组成一个新数组。 如果array 无法被分割成全部等长的区块,那么最后剩余的元素将组成一个区块。

JavaScript实用库:Lodash源码数组函数解析(一) chunk、compact、concat、arrayPush、copyArray、isArray、baseFlatten_第1张图片
接下来是chunk方法的源码:

function chunk(array, size, guard) {
  if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) {
    size = 1;
  } else {
    size = nativeMax(toInteger(size), 0);
  }
  var length = array == null ? 0 : array.length;
  if (!length || size < 1) {
    return [];
  }
  var index = 0,
      resIndex = 0,
      result = Array(nativeCeil(length / size));

  while (index < length) {
    result[resIndex++] = baseSlice(array, index, (index += size));
  }
  return result;
}

  第一个if判断是否有size传入函数,如果没有就默认size的大小为1。
  接下来就是命名的一个length变量复制数组的长度,如果数组为空,则length的值为0。
  接下来进行一次if判断,只要length的值为0即数组为空或者size小于0,则输出一个空字符串(这个处理也是避免函数传入size小于1的值后出现运行错误吧)
  下面主要的就是创建了一个新的数组result,它的大小是length / size的取整数。
  然后用baseSlice()函数对array数组进行分割数组导入创建的result数组中形成一个二维数组,最后输出result。


2、_.compact(array)
根据中文文档介绍,该函数能够处理原数组,生成一个新的数值,其中包含的元素不包含假值。 如false, null, 0, “”, undefined, 和 NaN 都是被认为是“假值”。

下面我们来看例子:
JavaScript实用库:Lodash源码数组函数解析(一) chunk、compact、concat、arrayPush、copyArray、isArray、baseFlatten_第2张图片接下来是compact方法的源码:

function compact(array) {
  var index = -1,
      length = array == null ? 0 : array.length,
      resIndex = 0,
      result = [];

  while (++index < length) {
    var value = array[index];
    if (value) {
      result[resIndex++] = value;
    }
  }
  return result;
}

  相信大家都看得懂前面的定义,都很清晰明白,就那个 length数组长度赋值那里用了点方法,如果 array数组为空则 length的值为0,。这个和第一点 chunk方法里的是一样的。
  关键的就是下面的循环处理了,首先我们看到 while里面的条件表达式:++index < length 里面的 ++index是使 index先+1再进行比较,也就是说我们的 index的值是先从0开始于 length进行比较的(其实我不明白为什么不使 index的初值为0,再进行 index++的运算,但是这两种好像都差不多)。
  然后就是取出array数组里的每一个值放到 if语句后面,如果为假值自然不能运行后面的将取出的数值存入result数组里面啦。


3、_.concat(array, [values])
根据中文文档介绍,该方法能够连接多个数组或者值形成一个新的数组

下面我们看一下例子:
JavaScript实用库:Lodash源码数组函数解析(一) chunk、compact、concat、arrayPush、copyArray、isArray、baseFlatten_第3张图片接下来是源码:

function concat() {
  var length = arguments.length;
  if (!length) {
    return [];
  }
  var args = Array(length - 1),
      array = arguments[0],
      index = length;

  while (index--) {
    args[index - 1] = arguments[index];
  }
  return arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1));
}

  前面就是取出对象的长度,如果为空,则输出一个空的数组。
  让后创建了一些变量 args一个长度为对象长度的空数组。array则是赋值 argument的第一个值,该值在要求里面也是一个数组。而 index则赋值为对象长度。
  然后就是从对象里面将值一个个放入 args数组中。
  最后的输出中用到了很多其他的函数,我在后面也把它们拿出来简单的看一下

  • arrayPush
    我们直接来看源码:
/**
 * Appends the elements of `values` to `array`.
 *
 * @private
 * @param {Array} array The array to modify.
 * @param {Array} values The values to append.
 * @returns {Array} Returns `array`.
 */
function arrayPush(array, values) {
  var index = -1,
      length = values.length,
      offset = array.length;

  while (++index < length) {
    array[offset + index] = values[index];
  }
  return array;
}

module.exports = arrayPush;

简单说一下,该函数是传入两个数组,将我们的 values数组追加到 array数组,和我们的JavaScript内置对象 push有异曲同工之处

  • isArray
    这个我就不说源码了,它就是用于判断是不是数组,如果是数组则输出turn,反之输出 false

  • copyArray
    这个我们也直接来看源码:

/**
 * Copies the values of `source` to `array`.
 *
 * @private
 * @param {Array} source The array to copy values from.
 * @param {Array} [array=[]] The array to copy values to.
 * @returns {Array} Returns `array`.
 */
function copyArray(source, array) {
  var index = -1,
      length = source.length;

  array || (array = Array(length));
  while (++index < length) {
    array[index] = source[index];
  }
  return array;
}

module.exports = copyArray;

这个函数的用法说的很简单,就是传入两个数组,第二个数组为空,用于复制第一个数组的值,实现方法也很简单,就是历遍循环赋值。

  • baseFlatten
    我们再来看看这个函数的源码:
/**
 * 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;
}

module.exports = baseFlatten;

这个函数我也不多说啦,后面的文章会提到,大家可以看看理解一下,该方法主要的功能就是扁平化数组,在我们最开始使用该函数的方式是:baseFlatten(args, 1),该过程的意义是,将我们的 args数组减少一层嵌套,原本是二维数组,换句话说就是转化为一维数组。


好啦,自己一点点码字写源码解析还是有点吃力的,我也是小白,如果有不对的地方请指出

新人不易,希望大家支持

你可能感兴趣的:(前端)