引入

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

今天要说的高阶函数的英文为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. Apache Kafka工作流程| Kafka Pub-Sub Messaging

    1.目标 在我们上一篇Kafka教程中,我们讨论了Kafka Docker.今天,我们将讨论Kafka Workflow.此外,我们将详细介绍Pub-Sub Messaging的工作流程以及Queue ...

  2. liunx 定时任务执行java程序配置流程

    java jar包使用build fat jar进行打包 ------------------liunx任务创建--------------------------- 1.查看现有任务计划: cron ...

  3. IP核——PLL

    一.Quartus II创建PLL 1.打开Quartus ii,点击Tools---MegaWizard Plug-In Manager 2.弹出创建页面,选择Creat a new custom ...

  4. 5_PHP数组_3_数组处理函数及其应用_4_数组和变量间的转换函数

    以下为学习孔祥盛主编的<PHP编程基础与实例教程>(第二版)所做的笔记. 数组和变量间的转换函数 1. list() 语言结构 程序: <?php $info = array('co ...

  5. SQL Server修改表的模式schema

    use myDBgo create schema myschema --先建立go alter schema myschema transfer dbo.myTable --移动对象至建立的schem ...

  6. 通过Git和GitHub项目管理

    用Git来管理代码文件 安装环境 windows 首先是安装git: 1.到git官网下载一个安装包 2.安装git,详细过程略 3.打开项目文件夹,并鼠标右击,打开git bash 4.从未使用过g ...

  7. vue + element ui开发过程中需要注意的几个点

    1.实现动态的数据双向绑定 关键字[$set]在这个需求开发的过程中还遇到深度克隆的问题 2:form表单的动态字段验证 关键字[promise.all] 3:动态表单验证关键字[el-form-it ...

  8. python 内建属性

    在python中创建一个类,它不仅有我们自定义的属性和方法,还有与生俱来的一些属性和方法,我们叫它内建属性. 下面是类常用内建属性列表. 常用专有属性 说明 触发方式 __init__ 构造初始化函数 ...

  9. 程序写入mycat中文乱码解决(也包括mysql编码修改)

    乱码问题可能出现的三个地方 1.程序连接的编码要设置 jdbc:mysql://192.168.1.1:8066/TESTDB?useUnicode=true&characterEncodin ...

  10. Python——Str

    在Python内存中,字符串是以unicode形式存储的. str格式,最常用的数据类型格式,分别有 (' ') 引号 ,(" ")双引号,(''' ''')三引号 开头和结尾的引 ...