编写程序的方式有很多,可能你将程序写的看起来像一系列的命令,这就是所谓的“命令式编程”,或者你在编写程序时,把东西保存在对象中,并与它们进行交互,来回发送消息,这就是“面向对象编程”,但是今天我谈论的是函数式编程,就像刚才说的两种一样,函数式编程是一种代码风格,这不是在讨论要不要加;
,或者{ }
是放在表达式的后面还是下面的问题,而是我们如何指导程序去执行,在技术上这叫做“编程范式”。那么为什么要关心这个呢?
有趣的函数 ✨
当我们讨论函数式编程的世界时,一切都是函数。概念上非常像数学上的概念,就是当我们在学校时候,老师对我们说的那样:
函数式一种值与值之间的特殊关系:给定的每一个输入都有确定的输出。
这个定义是非常重要的,因为这是我们项目的基础,叫做纯函数
,纯函数是这样的一种函数,它只依赖于它的输入,不依赖于外部的任何东西,期待你传递的参数,只返回输出,不会影响到其他地方,举个例子,下面的这些函数,一眼看上去你觉得有问题吗?
第一个版本 ❌
let age = 19
function getMyAge() {
console.log(`I'm ${age} years old.`)
}
getMyAge(age)
age = 20
getMyAge(age)
第二个版本 ✅
function getMyAge(age) {
return `I'm ${age} years old.`
}
getMyAge(19)
getMyAge(20)
在第一个版本中,函数从外部的作用域中寻找变量,一定程度上影响函数自身,在这种情况下的输出,理想状态下是只返回值,如果你注意到了的话。如果我们调用这个函数,使用相同的参数(甚至不传入参数),我们会得到不同的值。而在纯函数中这是不可能发生的。现在,你对函数式编程的好处有了一个基本的认识,其实好处还有更多,下面让我们看下它的强大?。
副作用
副作用是指在计算过程中与外部世界发生的任何相互作用,在使用纯函数时这是不会发生的,我们的代码会变得更加可预测,因为结果只依赖于它的输出,如果我们知道函数是这样的,那么对于它的输出,你可以预测它的结果......
可变性
可变性是指事物是可以改变的,这在函数式编程中是不推荐的。当我们有可变数据时,它的状态在创建之后不能够被改变,如果想进行一些改变,你需要创建新的值。
可变的例子
function changeFirstElem(array) {
array[0] = 'Lose yourself to dance'
}
const daftPunkPopSongs = ['Instant Crush', 'Get Lucky', 'One More Time']
changeFirstElem(daftPunkPopSongs)
不可变的例子
function changeFirstElem(array) {
const modifiedArray = ['Lose yourself to dance', ...array]
return modifiedArray
}
const daftPunkPopSongs = ['Instant Crush', 'Get Lucky', 'One More Time']
const modifiedArray = changeFirstElem(daftPunkPopSongs)
这是一件非常好的事情,因为我们让事情变得更加安全,使我们的代码更不容易出现bug,这意味着我们测试和调试代码变得更容易了。因为我们需要根据参数知道输出的情况,所以如果输出是错的,我们可以确定是我们的函数出了问题,而不是因为什么不确定的原因。
递归
递归是一种技术,让我们可以把一个问题分解成小块来解决,这有助于我们在和外界交互时避免一些副作用。
function myCount(int i) {
if(i >= 10) return 0
else return i + myCount(i+1)
}
myCount(1);
对我来说,递归使代码更易读,更简洁,在很多情况下我更喜欢使用迭代的方式。
函数式编程中的超级英雄?♀️
在递归之外,我们还有三种函数可以帮助我们处理数据,它们就是map-filter-reducer。在JS中,函数也可以被当做值,因此我们可以把函数当做参数传给其他函数。
Map
,给定一组数据,你可以传递一个函数来对数组中的每一项进行映射转换。
const numbers = [1, 2, 3];
const doubles = numbers.map(num => num * 2) //[2, 4, 6]
Filter
,接受一组数据,你可以传递一个条件函数并且返回筛选后的数据子集。
const numbers = [1, 2, 3];
const isGreaterThanOne = numbers.filter(num => num > 1) //[2, 3]
最后,Reduce
,给定一组数据,你可以将他们处理为单一的值。
const numbers = [1, 2, 3];
const mySum = numbers.reduce((accumulator, num) => accumulator + num) //6
结论?
我已经开始学习函数式编程了,这些优点激励着我开始并且坚持去看更多的资料,显然函数式编程也有缺点,但现在这些都不重要。你会用到我留在下面的资料,享受函数式编程的乐趣吧!
书籍
Hackernoon - Understanding Functional Programming Professor Frisby's Mostly Adequate Guide to Functional Programming Functional JavaScript Mini Book by Jichao Ouyang Pragmatic Function Javascript online book
论坛
Anjana Vankil - Functional Programming: What? Why? How?One of my favourites Anjana Vankil - Immutable data structures for functional JS Fun Fun Function Series
原文链接
The beauty of Functional Programming
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!