函数式编程

28 篇文章 1 订阅

诞生50多年之后,函数式编程(functional programming)开始获得越来越多的关注。
也许继"面向对象编程"之后,"函数式编程"会成为下一个编程的主流范式(paradigm),未来的程序员恐怕或多或少都必须懂一点。

初识函数式编程

如果我们想在控制台打印一个欢迎语句,例如:

hi,anna!

注意,这里hi之后的内容,即要欢迎的名字,需要变量定义,如变量name

非函数式编程:(命令式风格)

let name = "Anjana";

let greeting = "Hi,I'm"

console.log(greeting + name)

// "Hi,I‘m Anjana"

函数式编程:

function greet(name){return "Hi,I'm" + name;
}

greet("Anjana");

//"Hi,I'm Anjana"

函数式编程的第一个核心——尽可能的纯粹!

使用纯函数避免函数式编程的副作用:

函数式编程的副作用:函数的输出并不完全由给定的输入决定,函数的作用会受到外部某些因素的影响,例如全局变量等

纯函数编程思想:

函数结果只由输入决定,并且指定唯一输入后会返回唯一输出

  • 非纯函数:
 let name = "Anjana";

  function greet(){

  ​	console.log("Hi,I'm" + name);

  }

函数最后一行,直接调用没有输入。没有做为函数的参数,只是读取全局的值。

  • 纯函数:
function greet(name){return "Hi,I'm" + name;

  }

这里,对函数输出唯一重要的就是输入,传入形式为参数name。唯一要做的就是返回其输出。

函数式编程的第二个核心——使用JS高阶函数

JS高阶函数意味着可以将其他函数作为函数的输入,或者可以再函数中输出另一个函数,基本上就是将函数视为对象本身,可以传递其他函数,或者进行多重嵌套。这就是所谓的高阶函数,是函数式编程的核心之一。

看个简单例子:

 function makeAdjectifier(adjective){return fnction (string) {return adjective + " " + string;};

  }

  var coolifier = makeAdjectifier("cool");

  coolifier("conference");

 //"cool conference"

函数式编程的第三个核心:避免迭代

在使用函数式思想进行编程是,我们应尽量避免使用for或while等进行迭代,而尽量使用map,reduce或fileter这样的高阶函数,它们不仅可以把你想操作的列表作为输入,还可以作为一个函数去应用

map,filter,reduce作用示意图(在这里插入图片描述

函数式编程的第四个核心:避免数据变异

这里的变异,可以简单理解为对象的改变。但我们在实际开发中,时常需要一种永恒不变的东西,这种数据一旦创建就不会再次改变。

  • 非函数式编程引起变异:
 let rooms = ["H1","H2","H3"];

  rooms[2] = "H4";

  rooms;

  // ["H1","H2","H4"]
  • 函数式编程避免变异:
let rooms = ["H1","H2","H4"];

  let newRooms = rooms.map(function(rm){if (rm === "H3") { return "H4"; }else { return rm; }

  });

  newRooms; // ["H1","H2","H4"]

  rooms; // ["H1","H2","H3"]

我们可以看到,“rooms”里面的数据并没有改变。实际上我们是对rooms进行了一次拷贝,拷贝的数据进行了改变,而原始数据并没有改变。

但是像这种拷贝数据的方法会引起效率问题,每次改动数据,哪怕只有一点,程序都会进行一次拷贝,占用空间会越来越大。

使用持久性数据结构:解决效率问题

持久性数据结构工作方式:

假设我们有这么一个数组
在这里插入图片描述
按照之前的方法,我们要改变数据的同时,还要避免数据变异,需要拷贝一份此数组,对拷贝后的数组进行操作。例如将"H3"改为"H4":
在这里插入图片描述
而持久性工作方式则不需要拷贝,它是将整个数组看成一个树状结构,数组上的每个数据看成树上的每片“叶子”,如果修改数据,就将新数据看成一个“新的叶子”,改变树的结点结构就可以实现数据的改变:
在这里插入图片描述
在这里插入图片描述
这样我们在修改数据时,添加数据“叶子”(即要修改的数据),然后修改树上的节点,就可以实现数据的改变,而不是每次拷贝整个数组。这样就节省了大量的内存空间。
我们可以通过引用一系列的库在JS中实现这种效果:

学习更多关于函数式编程,推荐MRC编写的函数式编程介绍。传送门:

https://codewords.recurse.com/issues/one/an-introduction-to-functional-programming

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值