Sky
HOME
HOME
  • 前端笔记

    • CSS

      • 盒子模型
      • 屏幕单位
      • CSS 性能优化
    • JavaScript

      • Methods

        • Scheduler
        • Deep Clone
        • Curry
        • Calculation Function
        • debounce & throttle
      • Function bind
      • Array reduce
      • cross domain
      • event loop
      • ajax
      • event
      • context
      • inheritance
      • prototype
    • HTML

      • html render
      • forbidden <a>
      • <meta>
      • <script>
    • uni-app

      • scroll table

Array.prototype.reduce() | 迭代

语法

    arr.reduce(callback[, initialValue])

参数

  • callback

    • 执行数组中每个值的函数,包含四个参数:
      • accumulator
        • 累计器累计回调的返回值;它是上一次调用回调时返回的累积值,或 initialValue
      • currentValue
        • 数组中正在处理的元素
      • currentIndex
        • 数组中正在处理的当前元素的索引。如果提供了 initialValue,则索引号为 0,否则索引为 1
      • array
        • 调用 reduce() 的数组
  • initialValue

    • 作为第一次调用 callback 函数时的第一个参数的值。如果没有提供初始值,则将使用数组中的第一个元素。在没有初始值的空数组上调用 reduce 将报错

实现

  1. 判断 this 是否为 null 或 undefined
  2. 判断 callback 是否为函数
  3. 初始化变量
  4. 如果没有提供 initialValue,则数组的第一个有效值作为累加器的初始值 k++
  5. 用上文 k 值继续进行遍历

/**
 * 数组的reduce方法
 * @param {function} callback 回调函数
 * @param {any} initialValue 初始值
 * @returns {any} 返回值
 * 
 * */

Array.prototype.reduce = function (callback, initialValue) {
    if (this === null || this === undefined) {
        throw new TypeError('Cannot read property "reduce" of null or undefined');
    }
    
    if (Object.prototype.toString.call(callback) !== '[object Function]') {
        throw new TypeError(callback + ' is not a function');
    }
    
    /**
     * Object
     *  当调用或者构造 Object() 构造函数本身时,其返回值是一个对象。
     *  如果该值是 null 或者 undefined,它会生成并返回一个空对象。
     *  如果该值已经是一个对象,则返回该值。
     *  否则,它将返回与给定值对应的类型的对象。
     * */ 
    let O = Object(this);

    /**
     * 所有非数值转换成0;
     * 所有大于等于 0 等数取整数部分;
     * */ 
    let len = O.length >>> 0;
    let k = 0;
    let accumulator = initialValue;

    
    // 如果第二个参数为undefined的情况下,则数组的第一个有效值作为累加器的初始值
    if (accumulator === undefined) {

        // 如果超出数组界限还没有找到累加器的初始值,则TypeError
        if (len === 0) {
            throw new TypeError('Reduce of empty array with no initial value');
        }
        for (; k < len; k++) {
            if (k in O) {
                accumulator = O[k];
                // 这里导致没有提供 initialValue 时,数组的第一个元素会被跳过 k 从1开始
                k++;
                break;
            }
        }
    }
    
    // 以k值继续进行遍历
    for (; k < len; k++) {
        if (k in O) {
            accumulator = callback.call(undefined, accumulator, O[k], k, O);
        }
    }

    return accumulator;
}
    
最近更新: 2023/12/5 14:55
Contributors: liujw155@outlook.com
Prev
Function bind
Next
cross domain