写在之前

上两周精力用来重构公司的活动项目的构建了。之前很难用,使用webpack4重构之后,很安逸。代码组织也更合理了。

所以,lodash我又回来了。

使用

_.drop(array, [n=1])

创建一个切片数组,去除array前面的n个元素。(n默认值为1。)

demo

 * _.drop([1, 2, 3]);
 * // => [2, 3]
 *
 * _.drop([1, 2, 3], 2);
 * // => [3]
 *
 * _.drop([1, 2, 3], 5);
 * // => []
 *
 * _.drop([1, 2, 3], 0);
 * // => [1, 2, 3]

drop接收两个参数,第一个参数是一个数组,第二个参数是数字(不传默认为1)。

源码

function drop(array, n, guard) {
  var length = array == null ? 0 : array.length; // 数组不能传null,否则默认长度为0,在下边一行代码直接返回
  if (!length) {
    return [];
  }
  n = (guard || n === undefined) ? 1 : toInteger(n); // n不存在,默认为1
  return baseSlice(array, n < 0 ? 0 : n, length); // n如果为-2,则被修正为0,显然drop([1,2,3],-1) 应该不做任何修改直接返回
}

如果我们传入的数组是drop([1,2,3,4],2),执行到baseSlice的时候,实际调用的情况是baseSlice([1,2,3,4],2,4)

baseSlice源码

function baseSlice(array/** [1,2,3,4]**/, start/** 2**/, end/** 4**/) {
  var index = -1,
      length = array.length; //4

  if (start < 0) { // 对传入负数的处理
    start = -start > length ? 0 : (length + start);
  }
   // start => 2
  end = end > length ? length : end; //end截止不可能大于需要被切片的数组的长度,很简答,不多解释
  // end => 4
  if (end < 0) {
    end += length;
  }
  length = start > end ? 0 : ((end - start) >>> 0); // 4-2 =2   >>>0 位操作符,舍去浮点部分
  start >>>= 0; // 舍去浮点部分

  var result = Array(length); // Array(2),length =>2 ,start=>2,end=>4
  while (++index < length) { // 遍历,返回需要的result
    result[index] = array[index + start]; 
  }
  return result;
}

关于位操作符>>>,所有的按位操作符的操作数都会被转成补码(two's complement)形式的有符号32位整数,浮点部分会被直接忽略掉,更多的内容可以看这里

slice的源码显然考虑更多的情况。

  • start为负数,还要根据length的大小做一层判断。

    if (start < 0) { //  传入的是-5,而length为4,那么start就为0;如果-5,length:8,start:3
        start = -start > length ? 0 : (length + start);
    }
    // start为负数时,起始位置从数组的右侧向左的第`-start`位置。
  • end为负数的情况

     if (end < 0) {
        end += length;
     }
     // 如果end是-1,如果length为5,那么此时end就是4
     // 更形象一点就是slice([1,2,3,4,5],0,-1) 等于 slice([1,2,3,4,5],0,4)
  • start>end的情况,显然不合理,设置length为0,返回的结果是一个空数组。

最普通的一个
301 声望41 粉丝

永远不要做你擅长的事。


引用和评论

1 篇内容引用
0 条评论