zoukankan      html  css  js  c++  java
  • lodash.slice

    稀疏数组和密集数组

    稀疏数组 Sparse arrays

    一般来说,JavaScript 中的数组都是稀疏数组-它们可以拥有空槽,所谓空槽,指的就是数组的某个位置没有任何值,既不是 undefined,也不是 null,因为数组只是索引到值的简单映射。

    let a = new Array(3);
    
    console.log(a); // (3) [空 × 3]
    console.log(a[0]); // undefined
    
    a.forEach(function (x, i) { console.log(i, x) }); // 没有打印任何东西
    a.map(function (x, i) { return i }) // (3) [空 × 3]
    

    密集数组 Dense arrays

    let a = Array.apply(null, Array(3)); // 相当于 Array(undefined, undefined, undefined)
    
    console.log(a); // [ undefined, undefined, undefined ]
    console.log(a[0]); // undefined
    
    a.forEach(function (x, i) { console.log(i+". "+x) });
    
    // 0 undefined
    // 1 undefined
    // 2 undefined
    
    a.map(function (x, i) { return i }) // [ 0, 1, 2 ]
    

    位移操作符

    按位移动操作符有两个操作数:第一个是要被移动的数字,而第二个是要移动的长度

    移动的方向根据操作符的不同而不同。

    按位移动会先将操作数转换为大端字节序顺序(big-endian order)的32位整数,并返回与左操作数相同类型的结果。右操作数应小于 32位,否则只有最低 5 个字节会被使用。

    Big-Endian: 高位字节排放在内存的低地址端,低位字节排放在内存的高地址端,又称为"高位编址"。

    Big-Endian是最直观的字节序:

    1. 把内存地址从左到右按照由低到高的顺序写出;
    2. 把值按照通常的高位到低位的顺序写出;
    3. 两者对照,一个字节一个字节的填充进去。

    << 左移

    该操作符会将第一个操作数向左移动指定的位数。向左被移出的位被丢弃,右侧用 0 补充

    9 (base 10) -> 00000000000000000000000000001001 (base 2)
    
    console.log(9 << 2); // 36
    // 00000000000000000000000000001001 -> 00000000000000000000000000100100 = 36 (base 10)
    

    >> 有符号右移

    该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,拷贝最左侧的位以填充左侧。由于新的最左侧的位总是和以前相同,符号位没有被改变。所以被称作符号传播

    console.log(9 >> 2); // 2
    // 00000000000000000000000000001001 -> 00000000000000000000000000000010 = 2 (base 10)
    
    console.log(-9 >> 2 ); // -3 因为符号被保留了
    // 11111111111111111111111111110111 -> 11111111111111111111111111111101 = -3 (base 10)
    

    >>> 无符号右移

    该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,左侧用0填充。因为符号位变成了 0,所以结果总是非负的。(译注:即便右移 0 个比特,结果也是非负的。)

    对于非负数,有符号右移和无符号右移总是返回相同的结果。例如 9 >>> 2 和 9 >> 2 一样返回 2:

    console.log(9 >>> 2); // 2
    // 00000000000000000000000000001001 -> 00000000000000000000000000000010 = 2 (base 10)
    

    但是对于负数却不尽相同。 -9 >>> 2 产生 1073741821 这和 -9 >> 2 不同:

    console.log(-9 >>> 2); // 1073741821
    // 11111111111111111111111111110111 -> 00111111111111111111111111111101 = 1073741821 (base 10)
    

    lodash.slice

    console.log([1, 2, 3, 4].slice(-1))
    
    
    /**
     * 裁剪数组,从 start 位置开始到 end 结束,但不包括 end 本身的位置。
     * 代替 Array.prototype.slice,确保密集数组被返回。
     *
     * @param {Array} array 要裁剪的数组
     * @param {number} [start=0] 开始的位置 | 负指数将被视为距结束的偏移量。
     * @param {number} [end=array.length] 结束的位置 | 负指数将被视为距结束的偏移量。
     * @returns {Array} 返回裁切后的数组
     * @example
     *
     * var array = [1, 2, 3, 4]
     * _.slice(array, 2)
     * // => [3, 4]
     */
    function slice(array, start, end) {
      // 若 array 为 null 返回 []
      let length = array == null ? 0 : array.length
      if (!length) {
        return []
      }
    
      // 若 start 为 null 取第 0 位
      start = start == null ? 0 : start
      // 若 end 为 undefined(没传该值),end 取数组 length
      end = end === undefined ? length : end
      // start 为负值,若大于数组长度,start 取第零位,否则从最后以为往前减
      if (start < 0) {
        start = -start > length ? 0 : (length + start)
      }
      // 若结束位置大于数组 length 取 length
      end = end > length ? length : end
      if (end < 0) {
        end += length
      }
      // x >>> 0 保证 x 为数字类型且为正整数,在无意义的情况下缺省值为0。
      length = start > end ? 0 : ((end - start) >>> 0)
      // start = start >>> 0
      start >>>= 0 
      
      // 构建新数组并返回
      let index = -1
      const result = new Array(length)
      while (++index < length) {
        result[index] = array[index + start]
      }
      return result
    }
    
    export default slice
    
  • 相关阅读:
    日期格式化
    面向对象高级编程——使用__slots__
    面向对象编程——实例属性和类属性(六)
    面向对象编程——获取对象信息(五)
    面向对象编程——类方法和静态方法(八)
    面向对象编程——多重继承(七)
    面向对象高级编程——使用@property
    python常用模块——logger模块
    python常用模块——hashlib模块
    面向对象编程——super进阶(十)
  • 原文地址:https://www.cnblogs.com/guangzan/p/13221873.html
Copyright © 2011-2022 走看看