zoukankan      html  css  js  c++  java
  • 浅谈JS高阶函数

    引入

    我们都知道函数是被设计为执行特定任务的代码块,会在某代码调用它时被执行,获得返回值或者实现其他功能。函数有函数名和参数,而函数参数是当调用函数接收的真实的值。

    今天要说的高阶函数的英文为Higher-order function, 高阶函数的高阶是什么意思呢?

    定义

    至少满足下列一个条件的函数

    • 接收一个或多个函数作为输入
    • 输出一个函数

    怎么理解这么个东西呢?引言里说过了,函数实际上都是指向某个变量。既然变量可以是一个向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数

    //一个简单的高阶函数
    function add(x,y,f){
        return f(x)+f(y);
    }
    var x=add(-5,6,Math.abs);  //-> 11

    一些常见的高阶函数

    JS中设置了一些高阶函数,比如Array.prototype.mapArray.prototype.filterArray.prototype.reduce,他们接收一个函数作为参数,并应用这个函数到列表的每一个元素。

    Array.prototype.map

    map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果,原始数组不会改变。

    举个栗子~我们有个函数f(x)=x2,要把这个函数作用在一个数组[1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map实现:

    fuction pow(x){
        return x*x;
    }
    var arr=[1, 2, 3, 4, 5, 6, 7, 8, 9];
    var result=arr.map(pow);    //[1, 4, 9, 16, 25, 36, 49, 64, 81]
    console.log(results);
     

    值得注意的点:map()传入的参数是pow,即一个函数对象本身。

    虽然不用高阶函数依靠循环也能实现上述功能,但是作为高阶函数可以计算任意复杂的函数,也体现了高阶函数的价值。

    Array.prototype.reduce

    reduce()方法对数组中的每个元素执行一个提供的reducer函数(升序执行),将其结果汇总为单个返回值。

    Arrayreduce()把一个函数作用在这个Array[x1, x2, x3...]上,这个函数必须接收两个参数,reduce()把结果继续和序列的下一个元素做累积计算,其效果就是:

    [x1, x2, x3, x4].reduce(f) = f(f(f(x1, x2), x3), x4)
     

    比方说对一个Array求和,就可以用reduce实现:

    var arr=[1,3,5,7,9];
    arr.reduce(function(x,y){
        return x+y;
    });      //-> 25
     

    Array.prototype.filter

    filter() 方法创建一个新数组, 其包含通过提供函数实现的测试的所有元素,原始数组不会改变。

    filter也是一个常用的操作,它用于把Array的某些元素过滤掉,然后返回剩下的元素。 和map()类似,Arrayfilter()也接收一个函数。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是true还是false决定保留还是丢弃该元素。

    例如,在一个Array中,删除偶数,只保留奇数:

    var arr=[1,2,3,4,5,6,7,8];
    var r=arr.filter(function(x){
       return (x%2 !==0); 
    });
    console.log(r); //=>  [1,3,5,7]

    把一个Array中的空字符删除:

    var arr = ['A', '', 'B', null, undefined, 'C', '  '];
    var r = arr.filter(function (s) {
        return s && s.trim(); // 注意:IE9以下的版本没有trim()方法
    });
    r; // ['A', 'B', 'C']

    所以!filter()实际上是一个筛选函数。

    回调函数

    filter()接收的回调函数其实可以有很多个参数。通常我们仅使用第一个参数,表示Array的某个元素。回调函数还可以接收另外两个参数,表示元素的位置和数组本身:

    这里利用filter巧妙地实现了去重(我觉得很酷)

    var arr = ['A', 'B', 'C'];
    var r = arr.filter(function (element, index, self) {
        console.log(element); // 依次打印'A', 'B', 'C'
        console.log(index); // 依次打印0, 1, 2
        console.log(self); // self就是变量arr
        return true;
    });
    
    var r,arr=['apple', 'strawberry', 'banana', 'pear', 'apple', 'orange', 'orange', 'strawberry'];
    r=arr.filter(function(element,index,self){
        return self.indexOf(element)===index;
    });

    除了上述的几个常用的高阶函数,还有很多比较厉害的高阶函数,包括sort(),every(),finf(),findIndex(),forEach()等等,我会附在文章下面的参考中。

    函数作为返回值输出

    顾名思义,就是返回一个函数嘛,直接上例子:

    我们可以用Object.prototype.toString.call来获取对应对象返回的字符串,来判断类型

    let isType = type => obj => {
      return Object.prototype.toString.call( obj ) === '[object ' + type + ']';
    }
    
    isType('String')('123');        // true
    isType('Array')([1, 2, 3]);    // true
    isType('Number')(123);            // true
     

    总结

    高阶函数的功能很大程度上可以用普通的函数实现,但是高阶函数是代码更加抽象容易理解,使功能更加简洁,在函数复杂时可以很便捷地实现需要的功能,是个很好很好的东西~


    参考: 廖雪峰-高阶函数 ; 木易杨前端进阶-高阶函数

    转自掘金,原链接https://juejin.im/post/5daf0af4f265da5bbb1e57c0

  • 相关阅读:
    番剧下载器
    ☕️【系统设计】如何设计出优雅且实用的 API 接口
    对象在内存中的内存布局是什么样的?
    稍等,我手机帮你远程调试下代码!
    Redis持久化整理
    git fork模式整理
    Java Lambda 表达式源码分析
    Java Stream 源码分析
    JVM G1GC的算法与实现
    域控批量创建域用户,并授权组
  • 原文地址:https://www.cnblogs.com/GeniusZ/p/12069922.html
Copyright © 2011-2022 走看看