引入

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

今天要说的高阶函数的英文为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. 【vim小小记】vim的复制粘贴(包括系统剪贴板)

    1.vim常用复制粘贴命令 Vim的复制粘贴命令无疑是y (yank),p(paster),加上yy,P PS: vim有个很有意思的约定(我觉得是一种约定),就是某个命令的大小写都是实现某种功能,只 ...

  2. 【转帖】漏洞数量242:15,英特尔和AMD CPU谁更安全?

    漏洞数量242:15,英特尔和AMD CPU谁更安全? http://www.eetop.cn/cpu_soc/6946340.html 越来越多的用户开始怀疑哪种处理器可以最好地保护他们的计算机,数 ...

  3. Django框架之DRF 基于mixins来封装的视图

    基础视图 示例环境搭建:新建一个Django项目,连接Mysql数据库,配置路由.视图函数.序列化单独创建py文件 # 配置路由 from django.conf.urls import url fr ...

  4. SQL——AND、OR运算符

    一.AND.OR运算符基本说明 AND : 所有条件成立,则筛选出这条记录. OR : 只要其中一个条件成立,则筛选出这条记录. 演示student表: 二.AND运算符使用 查询name = '小明 ...

  5. 【LEETCODE】51、数组分类,简单级别,题目:581,830,1010,665

    package y2019.Algorithm.array; /** * @ClassName FindUnsortedSubarray * @Description TODO 581. Shorte ...

  6. 报告题目:HAO智能:HI + AI + OI

     报告题目:HAO智能:HI + AI + OI 报告摘要:大数据面向异构自治的多源海量数据, 旨在挖掘数据间复杂且演化的关联.大数据知识工程(BigKE)从大数据的 HACE定理开始, 从大知识建模 ...

  7. java List分组和排序处理

    在一些应用中,需要将List中的对象按某种情况分组或者排序处理.做个小结如下: 1. 如一个List中存放了ProductDoing对象,productDoing对象有rawTypeId 现在要求将r ...

  8. mongoose 警告信息 { useNewUrlParser: true } { useUnifiedTopology: true }

    问题: 解决:

  9. iOS应用图片尺寸制作脚本

    1.前提说明 通常 2.代码使用说明 2.1 脚本基本代码 #!/bin/sh iPhoneIcon() { sips -z 30 25 if_connected_green.png --out ./ ...

  10. Sqlite常用命令及基本知识

      sqlite菜鸟教程:http://www.runoob.com/sqlite/sqlite-tutorial.html   常用命令: .sqlite3 --从dos命令模式进入sqlite命令 ...