博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
简单解读高阶函数和纯函数
阅读量:7095 次
发布时间:2019-06-28

本文共 3149 字,大约阅读时间需要 10 分钟。

高阶函数

定义

高阶函数:英文叫Higher-order function,高阶函数是对其他函数进行操作的函数,可以将它们作为参数或返回它们。简单来说,高阶函数是一个函数,它接受函数作为参数或函数作为输出返回。

在不同的编程语言中都存在高阶函数,例如Javascript,Python,C#,C等等, JS中一个简单的高阶函数:

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

编写高阶函数,就是让函数的参数能接收别的函数。

高阶函数的应用

我们在平时的编程中都会使用到高阶函数,那么接下来一起看一下具体有哪些运用场景呢。

JavaScript内置高阶函数

JS中内置了一些常用的高阶函数,例如:Array.prototype.map,Array.prototype.filter和Array.prototype.reduce等等。 例如:使用Array的sort函数,sort接收一个函数作为参数。实现为数组arr排序。

const arr =[1,5,3];arr.sort((a, b) => a - b);复制代码

单例模式

什么事单利模式呢?在应用单例模式时,生成单例的类必须保证只有一个实力的存在,很多时候整个系统只需要拥有一个全局对象。比如在整个系统的配置文件中,配置数据有一个单例对象进行统一读取和修改,其他对象需要配置数据的时候也统一通过该单例对象来获取配置数据,这样就可以简化复杂环境下的配置管理。 单例模式:一个类能返回一个对象的引用(并且永远是同一个)和一个获得该实例的方法

var getSingle = function(fn) {    var ret;    return function() {        return ret || (ret = fn.apply(this, arguments));    };};复制代码

函数柯里化(curring)

函数柯里化又称为部分求值,一个curring的函数首先会接受一些参数,接收了这些参数之后,该函数并不会立即求值,而是继续调用另外一个函数,刚才传入的参数在函数形成的闭包中被保存起来,当函数被真正需要求值的时候,之前传入的所有参数都会被一次性用于求值。 简单例子

function curring(a) {    return function(b){        return a + b;    }} const add = curring(2);  // value为curring内返回的那个匿名函数const value = add(3); // 5复制代码

AOP

AOP(面向切面编程),主要是一些非业务模块的功能,针对全局性的功用代码模块,例如确认提示,日志消息,权限校验等等一些系统共用的部分。 例如我们增加一个在确认前弹出确认提示框。

// originFun为原函数,before和after为增强方法function constructor(originFun, before, after){    function _class(){        before.apply(this, arguments);        originFun.apply(this, arguments);        after.apply(this, arguments);    }    return _class;}// 加法运算,作为测试的原函数function confirm(){    console.log('已经确认提交!');}// AOP增强const confirmHandler = constructor(confirm,     function(){        console.log("我在原方法前执行")   },    function(){        console.log("我在原方法后执行")   });confirmHandler();// 我在原方法前执行// 已经确认提交!// 我在原方法后执行复制代码

通过高阶函数的形式,我们可以实现很多业务上的功能。

高阶函数还有很多用处,记住一点就是,它接受函数作为参数或函数作为输出返回。

JS — 纯函数

简单来说,满足下面两个条件就称为纯函数,

  1. 一个函数的返回结果只依赖于它的参数
  2. 函数在执行过程里面没有任何副作用【不会造成外部变量的改变】

一个函数的返回结果只依赖于它的参数

const a = 1;const foo = (b) => a+b;foo(3); // 4复制代码

从上面的例子可以看出,执行foo()函数,函数内的计算依赖外部变量a,因此执行foo函数的结果是会根据a的值变化而变化的,当我们能固定foo传入的参数,但是不能确定a的值,它的结果值是不可预料的,所以这个函数不是一个纯函数,

因为违背了我们的第一点:“一个函数的返回结果只依赖于它的参数”。

将上面的例子改动一下

const a = 1;const foo = (x, y) => x + y;foo(1, 3); // 4复制代码

执行foo函数,当我们确定了入参x,y时,就能得出唯一的一个输出结果,而且这个无论你在哪里运行都是一样的结果。所以foo(1, 3)的返回值是可预料的。

函数在执行过程里面没有任何副作用

例:

const foo = (obj, a) => {    obj.a = 2;    return obj.a + a;}const counter = {a: 1};foo(counter, 3); // 5counter.a // 2复制代码

上面的例子可以看出,我们执行foo函数,传入了两个参数,一个是counter对象,另外一个是数字常量,但是可以看出,运行完foo(counter,3)后在读取counter对象的a属性时,a的值发生了变化,说明这个函数是一个非纯函数,因为它的运行造成了外部变量发生改变,造成了副作用,

将上面的例子改动一下

const foo = (obj, a) => {    return obj.x + a;}const counter = {a: 1};foo(counter, 3) // 4counter.x // 1复制代码

这个时候的counter对象是没有发生改变的,foo(counter,3)执行后不会造成副作用。纯函数就是函数体内的任何操作都不能引起外部变量或者函数的变化。但是可以改变纯函数内部的变量 例:

const foo = (a) => {    const obj = { x: 1};    obj.x = 2;    return obj.x + a;}复制代码

纯函数的优点:纯函数在执行的时候不用担心它会发生意外的值,一个固定的输入肯定会得出固定的输出,不会产生不可预料的数据,并且不会对外部产生任何的影响。

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

你可能感兴趣的文章
GDI+ 学习记录(2): 画笔线帽 - Cap
查看>>
一张表里的多个字段值 取自 字典表里的text 的查询
查看>>
golang tcp socket
查看>>
特么的程序员励志故事(小IT职员在北京5年买了500W的房子)
查看>>
全选和反选 checkbox
查看>>
wget
查看>>
Python获取本机资源使用信息
查看>>
简述c语言的优缺点
查看>>
Linux设置用户登录提示
查看>>
Python调用第三方接口实现nagios短信报警
查看>>
centos修改大文件打开数(永久有效)
查看>>
mysql更改已有数据表的字符集,保留原有数据内容
查看>>
证书管理机构——CA
查看>>
js metro仿win8卡片效果
查看>>
我的友情链接
查看>>
Samba服务器的配置 , nfs配置解析
查看>>
Android Selector 与 Shape 基本用法
查看>>
通信工程师互联网技术数据库系统概述
查看>>
使用脚本实现自动化建立小Linux与命令移植
查看>>
rman差异增量及累积增量的区别
查看>>