纯函数这个这个词我相信小伙伴们多多少少都据说过,它是函数式编程的基础。本文主要是对纯函数进行探讨,包括基本概念,优势,运用的经典案例以及咱们平常该如何去合理的使用等等。javascript
首先咱们来看看纯函数的基本概念:html
相同的输入,老是会的到相同的输出,而且在执行过程当中没有任何反作用。
该怎么去理解上面的概念呢?咱们要把上面这句话拆成两部分来看。java
相同的输入,老是会获得相同的输出。react
来看看下面的例子:编程
let a = 1; function xAdd(x) { return x + a; }; xAdd(1); //2
上面这个函数就不是一个纯函数,由于在咱们程序执行的过程当中,变量a
极可能会发生改变,当变量a发生改变时,咱们一样执行xAdd(1)
时获得的输出也就不一样了。redux
再看另外一个例子:segmentfault
function sum(x, y) { return x + y; }; sum(1,2); //3
在这个例子中,符合相同的输入获得相同的输出这个概念,sum
是一个纯函数。数组
执行过程当中没有任何反作用。缓存
这里咱们要搞清楚什么是反作用,这里的反作用指的是函数在执行过程当中产生了外部可观察变化。dom
上面一系列操做均可以被称为是反作用。下面能够接着看一个修改外部数据从而产生反作用的例子:
let a = 1; function func() { a = 'b'; }; func(); console.log(a); // b
咱们运行了func
函数,外部的变量a
的值发生了改变,这就是产生了所谓的反作用,因此func
不是一个纯函数。当咱们这样进行修改:
function func2() { let a = 1; a = 'a'; return a }; func(); // a
函数fun2
不会对产生外部可观察变化,也就不会产生反作用,它就是一个纯函数。
一个纯函数,上面所说的两个条件缺一不可。
经过了解纯函数的概念,我相信有的小伙伴已经能感受到纯函数的一些的好处了:
既然纯函数有这么多好处,那么咱们来看看有哪些运用纯函数的经典案例。
数组的不少基本方法都是纯函数,例如map
,forEach
,filter
,reduce
等等。
Redux中三大原则之一使用纯函数来执行修改,其中就运用了Reducer来描述 action 如何改变 state tree。
Reducer 只是一些纯函数,它接收先前的 state 和 action,并返回新的 state。 --Redux
中文文档
Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库。我相信不少小伙伴也常常用到吧,这也是纯函数表明。
固然还有不少,这里就不一一举例了,总的来讲,纯函数仍是十分常见的。
在实际开发中,咱们能够合理的去运用纯函数来提升咱们的开发效率和代码质量。
咱们可使用纯函数的的方式来建立组件:
function Header(props) { return <h2>{props.text}</h2> }
对比一下使用Class(类)组件的方式建立组件:
class Header extends React.Component { render() { return <h1>{this.props.text}</h1> } }
咱们能够总结出纯函数组件的一些优势:
固然纯函数组件也有本身的缺点,例如:没有生命周期。
生命周期有时候并不可少,所幸如今咱们也已经有了很好的解决方案——react-hooks。利用hooks函数,咱们能够在函数组件中使用等价于生命周期,状态管理等方法。
在编写公共方法的时候,咱们尽可能用纯函数来进行编写。
假设咱们要编写一个把数组中的小写字母转为大写字母的公共方法:
let lists = ["q","w","e"]; let upperCaseLists = () => { let arr = []; for (let i=0, length= lists.length; i<length; i++) { let item = lists[i]; arr.push(item.toUpperCase()); } lists = arr; }
上面这个函数虽然能够实现逻辑复用,可是有反作用,确定是不适合用来作公共方法的,因此咱们要优化它:
let upperCaseLists = (value) => { let arr = []; for (let i=0, length= value.length; i<length; i++) { let item = value[i]; arr.push(item.toUpperCase()); } return arr; }
使用可读性更好的forEach
来优化:
let upperCaseLists = (value) => { let arr = []; value.forEach((item) => { arr.push(item.toUpperCase()); }) return arr; }
继续用map进一步优化:
let upperCaseLists = (value) => { return value.map((item) => item.toUpperCase()) }
是否是很简洁?具体方法怎么优化要根据实际状况和业务需求来。
https://segmentfault.com/a/11...
https://cuggz.blog.csdn.net/a...
纯函数这个概念其实并不复杂,在没有深刻了解以前咱们工做中也必定遇到过,也在不经意间用过。只有要合理的去运用它,就是开发中的一把利器。