• 学习笔记—前端基础之ES6的数组


    日常的学习笔记,包括 ES6、Promise、Node.js、Webpack、http 原理、Vue全家桶,后续可能还会继续更新 Typescript、Vue3 和 常见的面试题 等等。

    reduce

    let r = [1, 2, 3, 4, 5].reduce((total, num) => {
        return total + num
    })
    console.log(r);
    

    reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。

    reduce() 可以作为一个高阶函数,用于函数的 compose

    (注:reduce() 对于空数组是不会执行回调函数的。)

    简单来说,reduce 中会接受一个函数,函数的第一次循环,会将数组的前两项传入,并执行相应的计算,并将结果返回。往后的每一次循环,都会将上一次循环的结果传递到第一个参数中。

    initialValue

    initialValuereduce()的第二个参数,表示传递给函数的 初始值

    我们可以用它来计算购物车的总价格

    let r = [{price: 100, count: 1}, {price: 200, count: 2}, {price: 300, count: 3}].reduce((total, num) => {
        return total + num.price * num.count
    }, 0)
    console.log(r); // 1400
    

    这样我们整个数组默认的第一项就变成了 0,对于处理这种非数字数组非常好用。

    currentIndex

    currentIndex , reduce()函数的第三个参数,表示当前 元素的索引

    我们可以用它来将多个数据合并成一个数据。

    let keys = ['name', 'age'];
    let values = ['mxs', 18];
    let obj = keys.reduce((memo, cur, index) => {
      memo[cur] = values[index]
      return memo
    }, {});
    console.log(obj); // {name: 'mxs', age: 18}
    

    模拟compose函数逻辑

    compose 函数,函数调用扁平化。一个函数的运行结果当作实参传给下一个函数的这种操作,使复杂函数调用看起来更清晰。

    假设我们目前需要实现这样一个功能

    有两个 String 字符串,将其 拼接转换成大写 ,最后再 添加特殊字符并展示

    我们可能会这样解决这个问题。

    let str1 = 'mxs'
    let str2 = 'nb'
    function sum(a, b) {
        return a + b
    }
    function toUpper(str) {
        return str.toUpperCase()
    }
    function add(str) {
        return '***' + str + '***'
    } 
    console.log(add(toUpper(sum(str1, str2)))) // ***MXSNB***
    

    我们只模拟了三种功能,整个代码就已经很繁琐了。

    我们为了简化这种繁琐的代码,可以利用 compose函数 对其进行处理。

    function compose(...fns) {
      return function (...args) {
      let fn = fns.shift();
        return fns.reduce((a, b) => {
          return b(a)
        }, fn(...args))
      }
    }
    let r = compose(sum, toUpper, add)(str1, str2)
    console.log(r); // ***MXSNB***
    

    我们用一个名为 compose函数 的方法进行 闭包封装 ,这样会使输出代码看起来更整洁,逻辑更清晰。

    可以利用箭头函数简化 compose函数 代码

    let compose = (...fns) => (...args) => {
        let fn = fns.shift();
        return fns.reduce((a, b) => b(a), fn(...args))
    }
    

    同时,我们还可以在实现思路上进行简化。

    function compose(...fns) {
      return fns.reduceRight((a, b) => {
        return (...args) => {
          return a(b(...args))
        }
      })
    }
    

    这种实现方式非常难理解,但是也很好解释通,私下可以花点时间看一下。

    然后我们再对其写法进行简化,最终就会变成如下代码。

    let compose = (...fns) => fns.reduceRight((a, b) => (...args) => a(b(...args)))
    

    最终就成了一行代码。

    这行代码也被应用在 redux源码 中。

    手写实现reduce

    Array.prototype.reduce = function (callBack, prev) {
      for (let i = 0; i < this.length; i++) {
        if (prev == undefined) {
          prev = callBack(this[i], this[i + 1], i + 1, this);
          i++;
        } else {
          prev = callBack(prev, this[i], i, this)
        }
      }
      return prev
    }
    let r = [1, 2, 3].reduce((a, b, index, current) => a + b)
    let r2 = [1, 2, 3].reduce((a, b, index, current) => a + b, 100)
    console.log(r); // 6
    console.log(r2); // 106
    

    实现思路大体就是,利用将传入数组进行循环,执行函数并输出其结果。 假如有第二个参数,就对第二个参数进行处理。 若没有,则直接进行输出处理即可。

    map

    循环每一项,并对数组中的每一项进行处理,随后将处理后的结果以新数组的方式返回,不会改变原数组。

    let arr = [1, 2, 3]
    let newArr = arr.map(item => item * 2);
    console.log(newArr, arr) // [ 2, 4, 6 ] [ 1, 2, 3 ]
    

    filter

    过滤数组,将结果为 false 的项过滤掉,并将结果返回。

    let arr = [1, 2, 3]
    let newArr = arr.filter(item => item != 2);
    console.log(newArr, arr) // [ 1, 3 ] [ 1, 2, 3 ]
    

    some

    查看当前数组中是否存在与输出条件一致的结果,如果有则输出 true,反之为 false。 此方法与 every 方法相反

    let arr = [1, 2, 3]
    let newArr = arr.some(item => item == 2);
    console.log(newArr) // true 
    

    every

    查看当前数组中是否存在与输出条件不一致的结果,如果有则输出 true,反之为 false。 此方法与 some 方法相反

    let arr = [1, 2, 3]
    let newArr = arr.every(item => item == 2);
    console.log(newArr) // false 
    

    find

    查找数组中与函数条件一致的那一项结果,并将其返回。如果没找到,则返回 undefined

    let arr = [1, 2, 3]
    let newArr = arr.find(item => item == 2);
    console.log(newArr) // 2
    

    includes

    查找数组中是否包含函数条件的那一项结果,有则输出 true,没有输出 false

    let r = [1, 2, 3].includes(2)
    console.log(r); // true
    

    本篇文章由莫小尚创作,文章中如有任何问题和纰漏,欢迎您的指正与交流。
    您也可以关注我的 个人站点博客园掘金,我会在文章产出后同步上传到这些平台上。
    最后感谢您的支持!

  • 相关阅读:
    mysql设置不区分大小写
    java.lang.StackOverflowError: null
    与或非
    mysql自动备份
    Cause: com.microsoft.sqlserver.jdbc.SQLServerException: 不支持“variant”数据类型。
    MySQL主从复制 + Mycat实现读写分离
    Swing做的非阻塞式仿飞秋聊天程序
    Hudson + SVN + Maven 持续集成实现自动化编译、打包、部署(over SSH 和 Deploy war/ear to a container 两种部署方式)
    CMake安装(源码方式)
    多线程使用实例
  • 原文地址:https://www.cnblogs.com/moxiaoshang/p/14901801.html
Copyright © 2020-2023  润新知