动手实现 Redux(三):纯函数(Pure Function)简介
我们接下来会继续优化我们的 createStore 的模式,让它使我们的应用程序获得更好的性能。
但在开始之前,我们先用一节的课程来介绍一下一个函数式编程里面非常重要的概念 —— 纯函数(Pure Function)。
简单来说,一个函数的返回结果只依赖于它的参数,并且在执行过程里面没有副作用,我们就把这个函数叫做纯函数。这么说肯定比较抽象,我们把它掰开来看:
- 函数的返回结果只依赖于它的参数。
- 函数执行过程里面没有副作用。
函数的返回结果只依赖于它的参数
const a = 1
const foo = (b) => a + b
foo(2) // => 3
foo 函数不是一个纯函数,因为它返回的结果依赖于外部变量 a,我们在不知道 a的值的情况下,并不能保证 foo(2) 的返回值是 3。虽然 foo 函数的代码实现并没有变化,传入的参数也没有变化,但它的返回值却是不可预料的,现在 foo(2) 是 3,可能过了一会就是 4 了,因为 a 可能发生了变化变成了 2。
const a = 1
const foo = (x, b) => x + b
foo(1, 2) // => 3
现在 foo 的返回结果只依赖于它的参数 x 和 b,foo(1, 2) 永远是 3。今天是 3,明天也是 3,在服务器跑是 3,在客户端跑也 3,不管你外部发生了什么变化,foo(1, 2) 永远是 3。只要 foo 代码不改变,你传入的参数是确定的,那么 foo(1, 2) 的值永远是可预料的。
这就是纯函数的第一个条件:一个函数的返回结果只依赖于它的参数。
函数执行过程没有副作用
一个函数执行过程对产生了外部可观察的变化那么就说这个函数是有副作用的。
我们修改一下 foo:
const a = 1
const foo = (obj, b) => {
return obj.x + b
}
const counter = { x: 1 }
foo(counter, 2) // => 3
counter.x // => 1
我们把原来的 x 换成了 obj,我现在可以往里面传一个对象进行计算,计算的过程里面并不会对传入的对象进行修改,计算前后的 counter 不会发生任何变化,计算前是 1,计算后也是 1,它现在是纯的。但是我再稍微修改一下它:
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
现在情况发生了变化,我在 foo 内部加了一句 obj.x = 2,计算前 counter.x 是 1,但是计算以后 counter.x 是 2。foo 函数的执行对外部的 counter 产生了影响,它产生了副作用,因为它修改了外部传进来的对象,现在它是不纯的。
但是你在函数内部构建的变量,然后进行数据的修改不是副作用:
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 往控制台打印数据也是副作用。
纯函数很严格,也就是说你几乎除了计算数据以外什么都不能干,计算的时候还不能依赖除了函数参数以外的数据。
总结
一个函数的返回结果只依赖于它的参数,并且在执行过程里面没有副作用,我们就把这个函数叫做纯函数。
为什么要煞费苦心地构建纯函数?因为纯函数非常“靠谱”,执行一个纯函数你不用担心它会干什么坏事,它不会产生不可预料的行为,也不会对外部产生影响。不管何时何地,你给它什么它就会乖乖地吐出什么。如果你的应用程序大多数函数都是由纯函数组成,那么你的程序测试、调试起来会非常方便。
上一节:动手实现 Redux(二):抽离 store 和监控数据变化
动手实现 Redux(三):纯函数(Pure Function)简介的更多相关文章
- Function Programming - 纯函数(Pure Function)
纯函数的定义,非常重要!! Pure function 意指相同的输入,永远会得到相同的输出,而且没有任何显著的副作用. 老样子,我们还是从最简单的栗子开始: var minimum = 21; va ...
- 什么叫pure function(纯函数)
(来自:http://en.wikipedia.org/wiki/Pure_function) 在计算机编程中,假如满足下面这两个句子的约束,一个函数可能被描述为一个纯函数: 给出同样的参数值,该函数 ...
- redux中的reducer为什么必须(最好)是纯函数
为什么reducer最好是纯函数? 首先你得看看文档怎么说reducer的作用的,‘接收旧的 state 和 action,返回新的 state’,他起的是一个对数据做简单处理后返回state的作用. ...
- 动手实现 Redux(四):共享结构的对象提高性能
接下来两节某些地方可能会稍微有一点点抽象,但是我会尽可能用简单的方式进行讲解.如果你觉得理解起来有点困难,可以把这几节多读多理解几遍,其实我们一路走来都是符合“逻辑”的,都是发现问题.思考问题.优化代 ...
- 动手实现 Redux(二):抽离 store 和监控数据变化
上一节 的我们有了 appState 和 dispatch: let appState = { title: { text: 'React.js 小书', color: 'red', }, conte ...
- 动手实现 Redux(五):不要问为什么的 reducer
经过了这么多节的优化,我们有了一个很通用的 createStore: function createStore (state, stateChanger) { const listeners = [] ...
- react事件绑定的三种常见方式以及解决Cannot update during an existing state transition (such as within `render`). Render methods should be a pure function of props and state问题思路
在 React 组件中,每个方法的上下文都会指向该组件的实例,即自动绑定 this 为当前组件. 而且 React 还会对这种引用进行缓存,以达到 CPU 和内存的优化.在使用 ES6 classes ...
- 动手实现 Redux(六):Redux 总结
不知不觉地,到这里大家不仅仅已经掌握了 Redux,而且还自己动手写了一个 Redux.我们从一个非常原始的代码开始,不停地在发现问题.解决问题.优化代码的过程中进行推演,最后把 Redux 模式自己 ...
- react_结合 redux - 高阶函数 - 高阶组件 - 前端、后台项目打包运行
Redux 独立的集中式状态管理 js 库 - 参见 My Git 不是 react 库,可以与 angular.vue 配合使用,通常和 react 用 yarn add redux import ...
随机推荐
- 20170228 Z_po_send_email
FUNCTION zmm_po_send_email. function zmm_po_send_email. *"------------------------------------- ...
- hihoCoder 1586 Minimum 【线段树】 (ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛)
#1586 : Minimum 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 You are given a list of integers a0, a1, …, a2 ...
- SDIO卡 了解
SDIO接口是在SD接口基础上发展起来的,SDIO接口兼容SD接口.SDIO协议又在SD卡协议之上添加了CMD52(一般用来访问寄存器)和CMD53(字节和块传输)命令.SDIO和SD卡规范间的一个重 ...
- POJ3376 Finding Palindromes —— 扩展KMP + Trie树
题目链接:https://vjudge.net/problem/POJ-3376 Finding Palindromes Time Limit: 10000MS Memory Limit: 262 ...
- ssm使用velocity模板语言
1.在pom.xml里添加velocity模板语言支持的依赖 <!-- velocity模板语言支持包 --> <dependency> <groupId>org. ...
- 一步一步学Silverlight 2系列(10):使用用户控件
概述 Silverlight 2 Beta 1版本发布了,无论从Runtime还是Tools都给我们带来了很多的惊喜,如支持框架语言Visual Basic, Visual C#, IronRuby, ...
- codeforces 673B B. Problems for Round(模拟)
题目链接: B. Problems for Round time limit per test 2 seconds memory limit per test 256 megabytes input ...
- iOS 开发图片资源选择png格式还是jpg格式
对于iOS本地应用程序来说最简单的答案就是始终使用PNG,除非你有非常非常好的理由不用它. 当iOS应用构建的时候,Xcode会通过一种方式优化.png文件而不会优化其它文件格式.它优化得相当的好 他 ...
- 字符串转UTF-8码(%开头)
var str = '中'; var code = encodeURI(str); console.log(code); // => %E4%B8%AD
- caffe 入门实例3 fine-turning
占坑,使用fine-turning初始化参数...