引入

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

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

定义

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

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

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

//一个简单的高阶函数
function add(x,y,f){
    return f(x)+f(y);
}
,,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 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实现:

,,,,];
arr.reduce(function(x,y){
    return x+y;
});      //-> 25
 

Array.prototype.filter

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

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

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

,,,,,,,];
var r=arr.filter(function(x){
    !==);
});
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(');        // true
isType(, , ]);    // true
isType();            // true
 

总结

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


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

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

浅谈JS高阶函数的更多相关文章

  1. JS高阶函数的理解(函数作为参数传递)

    JS高阶函数的理解 高阶函数是指至少满足下列条件之一的函数. · 函数可以作为参数被传递 · 函数可以作为返回值输出 一个例子,我们想在页面中创建100个div节点,这是一种写法.我们发现并不是所有用 ...

  2. React.js高阶函数的定义与使用

    /* 高阶函数的简单定义与使用 一: 先定义一个普通组件 二: 用function higherOrder(WrappendComponent) { return } 将组件包裹起来,并用export ...

  3. js高阶函数

    我是一个对js还不是很精通的选手: 关于高阶函数详细的解释 一个高阶函数需要满足的条件(任选其一即可) 1:函数可以作为参数被传递 2:函数可以作为返回值输出 吧函数作为参数传递,这代表我们可以抽离一 ...

  4. js高阶函数应用—函数防抖和节流

    高阶函数指的是至少满足下列两个条件之一的函数: 1. 函数可以作为参数被传递:2.函数可以作为返回值输出: javaScript中的函数显然具备高级函数的特征,这使得函数运用更灵活,作为学习js必定会 ...

  5. js 高阶函数 闭包

    摘自  https://www.cnblogs.com/bobodeboke/p/5594647.html 建议结合另外一篇关于闭包的文章一起阅读:http://www.cnblogs.com/bob ...

  6. JS高阶函数的使用

    1.何为高阶函数呢? JavaScript的函数其实都指向某个变量.既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数.简单来说,就是对其他 ...

  7. JS 高阶函数

    笔记整理自:廖雪峰老师的JS教程 目录 概述 Array中的高阶函数 map(返回新的Array) reduce(返回新的Array) filter(返回新的Array) sort(返回同一Array ...

  8. js高阶函数应用—函数柯里化和反柯里化

    在Lambda演算(一套数理逻辑的形式系统,具体我也没深入研究过)中有个小技巧:假如一个函数只能收一个参数,那么这个函数怎么实现加法呢,因为高阶函数是可以当参数传递和返回值的,所以问题就简化为:写一个 ...

  9. js高阶函数map和reduce

    map 举例说明,比如我们有一个函数f(x)=x2,要把这个函数作用在一个数组[1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map实现如下: 由于map()方法定义在JavaScr ...

随机推荐

  1. 基于OpenCV制作道路车辆计数应用程序

    基于OpenCV制作道路车辆计数应用程序 发展前景 随着科学技术的进步和工业的发展,城市中交通量激增,原始的交通方式已不能满足要求:同时,由于工业发展为城市交通提供的各种交通工具越来越多,从而加速了城 ...

  2. go 渲染数据到文件

    //把数据写到文件里面 package main import ( "fmt" "text/template" "time" "o ...

  3. [SOJ #538]好数 [CC]FAVNUM(2019-8-6考试)

    题目大意:给定$n$个正整数,求$[l,r]$中第$k$小的”好数“.$l,r\leqslant10^{18},n\leqslant62$,出现的其他数均$\leqslant10^{50}$ 好数定义 ...

  4. SpringICO和DI区别

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的,今天和大家 ...

  5. C# vb实现浮雕特效滤镜效果

    在.net中,如何简单快捷地实现Photoshop滤镜组中的浮雕效果呢?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码: 设置授权 第一步 ...

  6. Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient报错,问题排查

    背景 最近在整合pyspark与hive,新安装spark-2.3.3以客户端的方式访问hive数据,运行方式使用spark on yarn,但是在配置spark读取hive数据的时候,这里直接把hi ...

  7. element ui改写实现两棵树

    使用element ui组件库实现一个table的两棵树的效果 效果如下,左边树自动展开一级,右边树默认显示楼层,然后可以一个个展开 代码如下 <el-table :data="rel ...

  8. 进入恢复模式(Recovery HD)

    进入恢复模式(Recovery HD) 1,选中要启动的虚拟机,随后点击VM菜单的启动按钮后面向下箭头,随后点击菜单项”打开电源时进入固件“. 2,在虚拟机里面,用上下键移动到”Enter setup ...

  9. 【洛谷 P2597】 [ZJOI2012]灾难(LCA)

    题目链接 考虑建一棵树,使一个生物灭绝时他的子树都会灭绝,显然这样答案就是以每个点为根的子树大小-1. 为什么原图不是一棵树,因为一个生物可能会以多个生物为食,所以按拓扑序来建树,把每个遍历到的点的父 ...

  10. iOS webrtc资料总结

    1. webrtc远端图像尺寸改变时,如何调整webrtc ios view的大小 https://www.jianshu.com/p/5e1a8f5bbcf7 2. webRTC实现音频通话听筒和扬 ...