引入

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

今天要说的高阶函数的英文为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. mysql 按照两个字段之和进行排序

    SELECT *,zan_num+fake_zan_num show_zan FROM `tf_news` order by show_zan desc TP实现 $news = M('news'); ...

  2. FineUI window弹层设置

    需在页面先设置   <f:Window ID="Window1" runat="server" Height="600px" Widt ...

  3. java接入微信JS-SDK

    在微信公众号开发中不可,jssdk的接入虽然不是必须,但是根据业务需求我们还是可能用到,下面是自己整理的关于java接入的jssdk的方法,这里是记录关于接入微信JS-SDK的准备工作,关于接入JS- ...

  4. JavaScript是单线程还是多线程(转)

    多线程要考虑线程之间的资源抢占,死锁,冲突之类一系列问题.JavaScript作为一门客户端脚本,貌似没有多线程的一些列问题.那么JavaScript是单线程还是多线程?通过查资料总结了JavaScr ...

  5. ubuntu 迅雷 XwareDesktop

    Xinkai/XwareDesktop Ubuntu上编译安装说明 Home    Ubuntu上编译安装说明    使用说明    升级到0.12    升级到0.9    发行版支持情况    名 ...

  6. JS基础_强制类型转换-Number

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  7. Mybatis全部标签与解释说明

    一.定义SQL语句 (1)select 标签的使用 属性介绍: id :唯一的标识符. parameterType:传给此语句的参数的全路径名或别名 例:com.test.poso.User或user ...

  8. day27-python之迭代器协议

    1.item系列方法 # class Foo: # def __getitem__(self, item): # print('getitem',item) # return self.__dict_ ...

  9. 如何在Hybris commerce里创建一个media对象

    进入backoffice的Media中心, 首先新建一个文件夹,用于存放即将创建的media对象: 取名为jerryimage: 然后创建一个新的media对象,取名jerryproductimage ...

  10. [LeetCode] 25. K 个一组翻转链表 ☆☆☆☆☆(链表)

    https://leetcode-cn.com/problems/reverse-nodes-in-k-group/solution/javadi-gui-fang-fa-100-by-chadriy ...