关注“重度前端”
助力前端深度学习
━━━━━
前言
最近看了下有些框架的实现机制,发现大量使用了纯函数。所以今天就把纯函数的概念重新梳理一遍。
1.什么是纯函数?
一个函数的返回结果只依赖于它的参数,并且在执行过程里面没有副作用,我们就把这个函数叫做纯函数。
用人类的话讲,纯函数的特性: 1.调用这个函数,只要我参数不变,这个函数的值始终不改变。 2.数值,对象使用这个函数,使用前后,自身的值不会发生变化,这就是指的副作用。也有人说是同输入同输出,我传入什么,掉用完,传出的就是什么。
let a = 0;
const fun = (val)=>{
return val + a;
}
let b = 1;
console.log(fun(b)) // 1
a=1
console.log(fun(b)) // 2
这个例子就不是一个纯函数,因为当a的值发生改变,函数输出的结果改变了,它不符合纯函数的第一条特性。
const a = 1
const foo = (obj, b) => {
obj.x = 2
return obj.x + b
}
const counter = { x: 1 }
foo(counter, 2) // => 4
counter.x // => 2
同样的道理这个例子虽然没有其它变量干扰函数的返回值,但是counter.x的值在调用函数之后发生了变化。
再
再举个正确的例子吧,下面函数便是一个纯函数!
const foo = (b) => {
const obj = { x: 1 }
obj.x = 2
return obj.x + b
}
虽然 foo
函数内部修改了 obj,但是 obj
是内部变量,外部程序根本观察不到,修改 obj
并不会产生外部可观察的变化,这个函数是没有副作用的,因此它是一个纯函数。
除了修改外部的变量,一个函数在执行过程中还有很多方式产生外部可观察的变化,比如说调用 DOM API 修改页面,或者你发送了 Ajax 请求,还有调用 window.reload
刷新浏览器,甚至是 console.log
往控制台打印数据也是副作用。
纯函数很严格,也就是说你几乎除了计算数据以外什么都不能干,计算的时候还不能依赖除了函数参数以外的数据。
为什么说纯函数在 JavaScript 很重要?
纯函数在函数式编程中被大量使用。而且诸如 ReactJS 和 Redux 等优质的库都需要使用纯函数。
不过,纯函数也可以用在平常的 JavaScript 开发中使用,不一定要限死在某个编程范例中。 你可以混合纯的和不纯的函数,这完全没问题。
并非所有函数都需要是纯的。 例如,操作 DOM 的按钮按下的事件处理程序就不适合纯函数。 不过,这种事件处理函数可以调用其他纯函数来处理,以此减少项目中不纯函数的数量。
可测试性和重构
另一个使用纯函数的原因是测试以及重构。
使用纯函数的一个主要好处是它们可以直接测。 如果传入相同的参数,它们将始终产生相同的结果。
同时纯函数还使得维护和重构代码变得更加容易。你可以放心地重构一个纯函数,不必操心没注意到的副作用搞乱了整个应用而导致终调试地狱。(译注:如果项目中充斥着副作用,那么函数/模块之间的逻辑可能互相交织耦合,在后期新增逻辑时可能由于依赖复杂而难以重构,更常见的是开发为了应付需求而不断的引入新的副作用到原本的逻辑上从而导致代码变得越来越糟糕。)
正确地使用纯函数可以产生更加高质量的代码。并且也是一种更加干净的编码方式。
总结
一个函数的返回结果只依赖于它的参数,并且在执行过程里面没有副作用,我们就把这个函数叫做纯函数。
为什么要煞费苦心地构建纯函数?因为纯函数非常“靠谱”,执行一个纯函数你不用担心它会干什么坏事,它不会产生不可预料的行为,也不会对外部产生影响。不管何时何地,你给它什么它就会乖乖地吐出什么。如果你的应用程序大多数函数都是由纯函数组成,那么你的程序测试、调试起来会非常方便。
参考资料:
http://huziketang.mangojuice.top/books/react/lesson32
http://www.fly63.com/article/detial/1274
https://blog.csdn.net/qq_37339364/article/details/82229986
【点个赞或者分享下,我就干的更带劲儿】
重度前端--助力深度学习
为web前端同行提供有价值、有深度的技术文章
官网:http://bigerfe.com【建设】
长按二维码关注我