• 【函数】高阶函数


    目录:

    1、高阶函数

    2、map/ reduce/ filter

    3、flat

    4、高阶函数在实际开发中的意义

    高阶函数

      高阶函数是对其他函数进行操作的函数,可以将它们作为参数或返回它们。简单来说,高阶函数是一个函数,它接收函数作为参数或将函数作为输出返回。

      众所周知,JS 中的函数其实都指向某个变量,既然变量可以指向函数,函数的参数可以接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数叫做高阶函数。JS 是一种弱类型的语言,JS 中的函数既不对输入的参数也不对函数的输出值做强定义和类型检查,那么函数就可以成为参数也可以成为输出值,这就体现了 JS 对高阶函数的原生支持。

    map/ reduce/ filter

       map()、reduce()、filter() 是原生高阶函数。

       (  map(): https://www.runoob.com/jsref/jsref-map.html

      现在有一个需求:创建一个新数组,其中的值是原数组的值的两倍。

      有的人可能会想到通过循环去实现:

    1 const arr1 = [1, 2, 3, 4];
    2 const arr2 = [];
    3 for( let i = 0; i < arr1.length; i++ ){
    4     arr2.push( arr1[i] * 2 );
    5 }
    6 console.log( arr2 );    //输出:[ 2, 4, 6, 8 ]

      上面是常规做法,可以实现需求。接下来了解一下这些高阶函数,然后使用高阶函数的思想来实现需求。

    map :

      在 JS 里有一个原生的 map 方法, 它接收一个函数作为参数,数组中的每个元素都会执行这个函数,它会创建一个新的数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果,这个函数有 3 个参数,第一个参数是必选参数,表示当前元素的值,第二、三个元素是可选参数,表示当前元素的索引以及当前元素所属的数组。

      为了了解一下参数,传入一个输出 3 个参数函数作为 map 方法参数,数组 arr1 中的每个元素都会执行这个函数。

    1 const arr1 = [1, 2, 3, 4];
    2 const arr2 = arr1.map(function(item, index, arr){
    3     console.log( item, index, arr );
    4 });

      运行结果:

       下面通过 map 函数实现实现需求(创建一个新数组,其中的值是原数组的值的两倍):

    1 const arr1 = [1, 2, 3, 4];
    2 const arr2 = arr1.map(function(item, index, arr){
    3     return item * 2 ;
    4 });
    5 console.log( arr2 );    //输出:[ 2, 4, 6, 8 ]

      上面,实现了需求,也可以用箭头函数来表示:

    1 const arr1 = [1, 2, 3, 4];
    2 const arr2 = arr1.map(item => item * 2);
    3 console.log( arr2 );    //输出:[ 2, 4, 6, 8 ]

    reduce :

      (  菜鸟教程中的 reduce(): https://www.runoob.com/jsref/jsref-reduce.html  )  

      

      reduce 方法接收一个函数作为累加器,函数为数组中的每个元素依次执行回调函数,它接收4个参数,第一个是初始值也就是上一次回调的返回值,第二个是当前元素值,第三个是当前索引,第四个是原数组。常用的参数只有返回值与当前元素值。

      现在有一个需求:计算数组元素相加后的总和

    1 let arr = [1, 2, 3, 4, 5];
    2 let sum = arr.reduce( (prev, cur) => {
    3     return prev + cur;
    4 }, 0);
    5 console.log( sum );     //输出:15

      上面,实现了需求。这里的 prev 表示上一次调用回调时返回的值或者是传入的初始值。这里,由于传入了初始值 0,所以最初 prev 的值为 0,cur 的值为数组的第一项 1,prev + cur =1, 返回值为 1 ,1作为下一轮回调的 prev 值,然后再继续与下一个数组项相加,以此类推,直至完成所有数组项的和并返回。

      还可以通过 reduce 方法实现数组去重。

    1 let arr = [1, 2, 2, 2, 3, 4, 5, 2, 2];
    2 let newArr = arr.reduce((prev, cur) => {
    3     prev.indexOf( cur ) === -1 && prev.push(cur);
    4     return prev;
    5 }, [])
    6 console.log( newArr );  //输出:[ 1, 2, 3, 4, 5 ]

      上面,实现了需求。由于传入了初始值 [ ],所以最初 prev 的值为 [ ],prev 的数组中不包含 cur 元素时,将 cur 元素 push 到 prev 数组中,从而达到数组去重的目的。

    filter :

      ( filter(): https://www.runoob.com/jsref/jsref-filter.html   ) )

      filter 方法主要用于对数组过滤与筛选。它会创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。

       现在有这样一个需求:请将对象数组中年龄大于 21 的对象组成新的对象数组。

    let persons = [
        { 'name' : 'Peter', age : 21 },
        { 'name' : 'Mark', age : 22 },
        { 'name' : "Tony", age : 23 },
        { 'name' : "xiaoxu", age : 20 },
        { 'name' : "Mona", age : 30 }
    ]
    let newAge = persons.filter( item => item.age>21 );
    console.log( newAge );

      执行结果:

       上面,通过数组 persons 调用 filter 方法,filter 方法的参数是一个函数,数组 persons 中的每个元素都会这个函数。

    flat

      flat 方法目前还没有在所有浏览器兼容,包括 node。

      数组的成员有时还是数组,flat 方法用于将嵌套的数组拉平,也就是所谓的数组扁平化,将多维数组变为一维数组,该方法会返回一个新数组,对原数据没有影响。

    let arr = [1, 2, 3, 4, [5, 6]];
    let arr1 = arr.flat();
    console.log( arr1 );    //输出:[1, 2, 3, 4, 5, 6]

      上面,arr 保存了一个多维数组,因为 flat 方法会返回一个新数组,所以定义一个新的变量 arr1 接收它,输出 arr1, 可以看到模拟的二维数组可以扁平化为一维数组。

      flat 方法默认只会拉平一层,如果想要拉平多层的数组嵌套,可以给 flat 方法传入一个整数参数,表示想要拉平的层数,它的默认值为 1,

    let arr = [1, 2, 3, 4, [5, 6 , [7, 8]]];
    let arr1 = arr.flat( 3 );
    console.log( arr1 );    //输出:[1, 2, 3, 4, 5, 6, 7, 8]

      上面,三维数组被扁平化了返回了一个一维数组。

      如果不确定有多少层数组嵌套,但是我们想要返回一个以为数组,可以使用 Infinity 关键字作为 flat 方法的参数。

    let arr = [1, 2, 3, 4, [5, 6 , [7, 8 , [9, 10, [11, 12]]]]];
    let arr1 = arr.flat( Infinity );
    console.log( arr1 );    

       执行结果:

    高阶函数在实际开发中的意义

       高阶函数可以分为 2 种,第一种是函数可以作为参数被传递,第二种是函数可以作为返回值输出。

      下面是高阶函数的第一种形式,将函数作为参数:

    function foo( f ){
        //判断实参是否为函数
        if( ( typeof f ) === "function" ){
            f();
        }
    }
    //调用
    foo( function(){} );

      上面,在调用函数时,输入一个函数作为参数,在函数内部执行这个传入的匿名函数。

      下面是高阶函数的第二种形式,将函数作为返回值。

    function foo(){
        return function(){};
    }
    //调用
    let f = foo();

      上面,调用函数的时候返回的仍然是一个函数。

      下面是一个高阶函数实际作用的例子:

    //回调函数
    let callback = ( value ) => {
        console.log( value );
    }
    let foo = ( value, fn ) => {
        if( typeof callback === 'function' ){
            fn( value );
        }
    }
    foo( 'hello', callback );   //输出:hello

      上面,调用 foo 时,foo 内部会调用 callback 函数即实现回调。

      注意,高阶函数并不是 JavaScript 的专利,但绝对是 JavaScript 编程的利器。高阶函数实际上就是对基本算法的再度抽象,可以利用这一点提高代码的抽象度,实现最大限度的代码重用编写出更简洁、更利于重构的代码。在 REACT 中,也是受到高阶函数的启发,才会有了高阶组件的概念。

  • 相关阅读:
    【转】请说出三种减少页面加载时间的方法。
    【转】Web前端性能优化——如何提高页面加载速度
    【转】数据分析sql常用整理
    【转】消息中间件系列之简单介绍
    Could not load file or assembly 'System.Core, Version=2.0.5.0 和autofac冲突的问题
    云主机与传统主机性能对比表
    真假云主机,VPS资料集合
    将网站部署到windows2003 iis6之后,出现asp.net程序页面无法访问情况
    想当然是编程最大的坑,记更新删除过期cookie无效有感
    FlashBuilder(FB/eclipse) 打开多个无效
  • 原文地址:https://www.cnblogs.com/xiaoxuStudy/p/12604515.html
Copyright © 2020-2023  润新知