高阶函数:英文叫Higher-order function。JavaScript的函数其实都指向某个变量。既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。

高阶函数是指至少满足下列条件之一的函数。

· 函数可以作为参数被传递

· 函数可以作为返回值输出

一个例子,我们想在页面中创建100个div节点,这是一种写法。我们发现并不是所有用户都是想把这100个div显示的的。所以就有第二种写法

  1. var appendDiv=function(){
  2. for(var i=0;i<100;i++){
  3. var div =document.createElement('div');
  4. div.innerHTML=i;
  5. document.body.appendChild(div);
  6. &emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;div.style.display='block';
  7. }
  8. }
  9. appendDiv();
  10. 复制代码

第二种写法

这是我们appendDiv传入了一个函数

  1. function(node){
  2. node.style.display='none';
  3. }
  4. 复制代码

然后在appendDiv中判断这个是否是function,如果是我们就执行他,把它传入appendDiv()中

  1. var appendDiv=function(callback){
  2. for(var i=0;i<100;i++){
  3. var div =document.createElement('div');
  4. div.innerHTML=i;
  5. document.body.appendChild(div);
  6. if(typeof callback=='function'){
  7. callback(div);
  8. //console.log(callback);
  9. }
  10. }
  11. }
  12. appendDiv(function(node){
  13. node.style.display='none';
  14. });
  15. 复制代码

结论

  1. div.style.display='block';//这段代码是不合理的,这段代码放进去成为了难以复用的程序,所以我们得用函数作为参数传进去
  2. //原理是这样的,function(node){node.style.display='block';}传入进去后,就相当于把这个匿名函数变成了callback函数
  3. //即
  4. var callback = function(node){
  5. node.style.display='block';
  6. }
  7. callback(div);//函数执行
  8. 复制代码

再给大家看一个比较简单的高阶函数

  1. function add(x, y, f) {
  2. return f(x) + f(y);
  3. }
  4. //当调用add(-5, 6,Math.abs)时,参数x,y和f分别接收-5,6和函数Math.abs,根据函数定义,可以推导计算过程为:
  5. //x = -5;
  6. //y = 6;
  7. //f = Math.abs;
  8. //f(x) + f(y) ==> Math.abs(-5) + Math.abs(6) ==> 11;
  9. //return 11;
  10. //用代码验证一下:
  11. add(-5, 6, Math.abs); // 11
  12. 复制代码

再给大家介绍几个高阶函数

一、map/reduce

如果你读过Google的那篇大名鼎鼎的论文“MapReduce: Simplified Data Processing on Large Clusters”,你就能大概明白map/reduce的概念。由于map()方法定义在JavaScript的Array中,我们调用Array的map()方法,传入我们自己的函数,就得到了一个新的Array作为结果:

  1. function pow(x) {
  2. return x * x;
  3. }
  4. var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
  5. arr.map(pow); // [1, 4, 9, 16, 25, 36, 49, 64, 81]
  6. //map()传入的参数是pow,即函数对象本身。
  7. //不需要map(),写一个循环,也可以计算出结果:
  8. var f = function (x) {
  9. return x * x;
  10. };
  11. var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
  12. var result = [];
  13. for (var i=0; i<arr.length; i++) {
  14. result.push(f(arr[i]));
  15. }
  16. //的确可以,但是,从上面的循环代码,我们无法一眼看明白“把f(x)作用在Array的每一个元素并把结果生成一个新的Array”。
  17. 复制代码

 所以,map()作为高阶函数,事实上它把运算规则抽象了,因此,我们不但可以计算简单的f(x)=x2,还可以计算任意复杂的函数,比如,把Array的所有数字转为字符串:

  1. var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
  2. arr.map(String); // ['1', '2', '3', '4', '5', '6', '7', '8', '9']
  3. //只需要一行代码。
  4. 复制代码

2、reduce():

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

  1. [x1, x2, x3, x4].reduce(f) = f(f(f(x1, x2), x3), x4)
  2. //比方说对一个Array求和,就可以用reduce实现:
  3. var arr = [1, 3, 5, 7, 9];
  4. arr.reduce(function (x, y) {
  5. return x + y;
  6. }); // 25
  7. 复制代码

二、filter

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

  1. //例如,在一个Array中,删掉偶数,只保留奇数,可以这么写:
  2. var arr = [1, 2, 4, 5, 6, 9, 10, 15];
  3. var r = arr.filter(function (x) {
  4. return x % 2 !== 0;
  5. });
  6. r; // [1, 5, 9, 15]
  7. //把一个Array中的空字符串删掉,可以这么写:
  8. var arr = ['A', '', 'B', null, undefined, 'C', ' '];
  9. var r = arr.filter(function (s) {
  10. return s && s.trim(); // 注意:IE9以下的版本没有trim()方法
  11. });
  12. arr; // ['A', 'B', 'C']
  13. 复制代码

 可见用filter()这个高阶函数,关键在于正确实现一个“筛选”函数。

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

  1. var arr = ['A', 'B', 'C'];
  2. var r = arr.filter(function (element, index, self) {
  3. console.log(element); // 依次打印'A', 'B', 'C'
  4. console.log(index); // 依次打印0, 1, 2
  5. console.log(self); // self就是变量arr
  6. return true;
  7. });
  8. //利用filter,可以巧妙地去除Array的重复元素:
  9. 'use strict';
  10. var r,
  11. arr = ['apple', 'strawberry', 'banana', 'pear', 'apple', 'orange', 'orange', 'strawberry'];
  12. r = arr.filter(function (element, index, self) {
  13. return self.indexOf(element) === index;
  14. });
  15. alert(r.toString());
  16. //去除重复元素依靠的是indexOf总是返回第一个元素的位置,后续的重复元素位置与indexOf返回的位置不相等,因此被filter滤掉了。
  17. 复制代码

三、sort排序算法

  因为Array的sort()方法默认把所有元素先转换为String再排序,结果'10'排在了'2'的前面,因为字符'1'比字符'2'的ASCII码小。如果不知道sort()方法的默认排序规则,直接对数字排序,绝对栽进坑里!

  幸运的是,sort()方法也是一个高阶函数,它还可以接收一个比较函数来实现自定义的排序。
  
  

  1. //要按数字大小排序,我们可以这么写:
  2. var arr = [10, 20, 1, 2];
  3. arr.sort(function (x, y) {
  4. if (x < y) {
  5. return -1;
  6. }
  7. if (x > y) {
  8. return 1;
  9. }
  10. return 0;
  11. }); // [1, 2, 10, 20]
  12. //如果要倒序排序,我们可以把大的数放前面:
  13. var arr = [10, 20, 1, 2];
  14. arr.sort(function (x, y) {
  15. if (x < y) {
  16. return 1;
  17. }
  18. if (x > y) {
  19. return -1;
  20. }
  21. return 0;
  22. }); // [20, 10, 2, 1]
  23. //默认情况下,对字符串排序,是按照ASCII的大小比较的,现在,排序应该忽略大小写,按照字母序排序。
  24. //要实现这个算法,不必对现有代码大加改动,只要我们能定义出忽略大小写的比较算法就可以:
  25. var arr = ['Google', 'apple', 'Microsoft'];
  26. arr.sort(function (s1, s2) {
  27. x1 = s1.toUpperCase();
  28. x2 = s2.toUpperCase();
  29. if (x1 < x2) {
  30. return -1;
  31. }
  32. if (x1 > x2) {
  33. return 1;
  34. }
  35. return 0;
  36. }); // ['apple', 'Google', 'Microsoft']
  37. //忽略大小写来比较两个字符串,实际上就是先把字符串都变成大写(或者都变成小写),再比较。
  38. //sort()方法会直接对Array进行修改,它返回的结果仍是当前Array:
  39. var a1 = ['B', 'A', 'C'];
  40. var a2 = a1.sort();
  41. a1; // ['A', 'B', 'C']
  42. a2; // ['A', 'B', 'C']
  43. a1 === a2; // true, a1和a2是同一对象
  44. 复制代码

转载于:https://juejin.im/post/5c36af5ff265da615705ad99

js高阶函数的理解的更多相关文章

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

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

  2. Python之高阶函数如何理解?

    我们先要了解一下什么是所谓的高阶函数: 看定义:什么是高阶函数? 高阶函数:我们知道一个函数可以作为参数传给另外一个函数,或者一个函数的返回值为另外一个函数(若返回值为该函数本身,则为递归),如果满足 ...

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

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

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

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

  5. 浅谈JS高阶函数

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

  6. JS 高阶函数

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

  7. js高阶函数

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

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

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

  9. js 高阶函数 闭包

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

随机推荐

  1. 微信小程序页面传值详解

    我们知道,在微信小程序中,从一个页面转到另一个页面,一般情况下可以通过navigate或redirect时候的url来携带参数,然后在目标页面的onLoad函数参数中获取这些url参数.例如:   / ...

  2. java类文件结构笔记

    注:新的博客地址 - https://zhengw-tech.com/archives/ 我们都知道java实现跨平台靠的是虚拟机技术,将源文件编译成与操作系统无关的,只有虚拟机能识别并执行的字节码文 ...

  3. 浅谈头文件(.h)和源文件(.cpp)的区别

    浅谈头文件(.h)和源文件(.cpp)的区别 本人原来在大一写C的时候,都是所有代码写在一个文件里一锅乱煮.经过自己开始写程序之后,发现一个工程只有一定是由多个不同功能.分门别类展开的文件构成的.一锅 ...

  4. Fastdfs文件系统扩容

    1.简介     FastDFS文件服务器在设计时,为了支持大容量,存储节点(服务器)采用了分卷(或分组)的组织方式.存储系统由一个或多个卷组成,卷与卷之间的文件是相互独立的,所有卷的文件容量累加就是 ...

  5. 怎么把jmeter汉化?

    1.在Jmeter 的bin目录下找到 jmeter.properties 文件 2.找到后复制一份出来用记事本打开,Ctrl+F输入 language 定位找到  #language=en  并且把 ...

  6. MySQL中information_schema 数据库 是干什么的

    MySQL中information_schema是什么 大家在安装或使用MYSQL时,会发现除了自己安装的数据库以外,还有一个information_schema数据库. information_sc ...

  7. CentOS7.5 使用Docker部署Jumpserver

    1.环境准备 # 查看系统版本 $ cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) # 查看内核版本 $ uname -a L ...

  8. 安卓menu的介绍与使用

    菜单之前是用户点击系统的菜单键才展示出来的,后来这个键渐渐被移除,菜单变成了点击任意的view都可以展示.菜单非为3种: 1.Options menu and action bar  选项菜单和操作栏 ...

  9. IdentityServer4 QuckStart 授权与自定义Claims

    最近在折腾IdentityServer4,为了简单,直接使用了官方给的QuickStart示例项目作为基础进行搭建.有一说一,为了保护一个API,感觉花费的时间比写一个API还要多. 本文基于ASP. ...

  10. Camunda 流程引擎的一种 Adapter 层实现

    上一篇说明了选择 Camunda 的理由.这一篇说明如何实现适配层. 当前还没有专门写一篇对 Camunda 各个功能的详细介绍.如果要获得比较直观的感受,可以下载 Modeler 或者使用在线版的 ...