了解 JavaScript 函数式编程 -- 什么是纯函数
栏目: JavaScript · 发布时间: 5年前
内容简介:silce 就是一个纯函数,没有改变初始的值。而我们常用的 splice 就是一个影响初始值的不纯的函数。副作用可能包括以下,但不限于:更改文件系统 往数据库插入记录 发送一个 http 请求 可变数据 打印/log 获取用户输入 DOM 查询 访问系统状态
-
DRY(不要重复自己,don't repeat yourself)
-
高内聚低耦合(loose coupling high cohesion)
-
YAGNI (你不会用到它的,ya ain't gonna need it)
-
最小意外原则(Principle of least surprise)
-
单一责任(single responsibility)等等。
看一个纯函数的例子
- 纯函数不改变原始的输入值。避免无用的副作用
var xs = [1,2,3,4,5]; // 纯的 xs.slice(0,3); //=> [1,2,3] xs.slice(0,3); //=> [1,2,3] xs.slice(0,3); //=> [1,2,3] // 不纯的 xs.splice(0,3); //=> [1,2,3] xs.splice(0,3); //=> [4,5] xs.splice(0,3); //=> [] 复制代码
silce 就是一个纯函数,没有改变初始的值。而我们常用的 splice 就是一个影响初始值的不纯的函数。
副作用
副作用可能包括以下,但不限于:
更改文件系统 往数据库插入记录 发送一个 http 请求 可变数据 打印/log 获取用户输入 DOM 查询 访问系统状态
我们可以概括来看,只要和外部环境发生一定交互的都是副作用。我们在书写纯函数的时候尽量要保持无副作用的交互。
当然并不是要禁止一切的副作用,而是说我们需要在可控的范围内去发生。
追求纯函数
我们在初中开始学习函数的时候知道: 函数是不同数值之间的特殊关系:每一个输入值返回且只返回一个输出值 。
- 我们要保持这种逻辑,让函数得到一个确认的值。
可缓存性(Cacheable)
下面来实现一个缓存的函数
var squareNumber = memoize(function(x){ return x*x; }); squareNumber(4); //=> 16 squareNumber(4); // 从缓存中读取输入值为 4 的结果 //=> 16 squareNumber(5); //=> 25 squareNumber(5); // 从缓存中读取输入值为 5 的结果 //=> 25 复制代码
这里看看 memoize 缓存函数是怎么实现的
var memoize = function(f) { var cache = {}; return function() { var arg_str = JSON.stringify(arguments); cache[arg_str] = cache[arg_str] || f.apply(f, arguments); return cache[arg_str]; }; }; 复制代码
下面会看到这种缓存函数的实用性
可移植性/自文档化
纯函数是完全自给自足的,它需要的所有东西都能轻易获得。仔细思考思考这一点...这种自给自足的好处是什么呢?首先,纯函数的依赖很明确,因此更易于观察和理解
并行代码
最后一点,也是决定性的一点:我们可以并行运行任意纯函数。因为纯函数根本不需要访问共享的内存,而且根据其定义,纯函数也不会因副作用而进入竞争态(race condition)。
并行代码在服务端 js 环境以及使用了 web worker 的浏览器那里是非常容易实现的,因为它们使用了线程(thread)。不过出于对非纯函数复杂度的考虑,当前主流观点还是避免使用这种并行。
总结
运用以上的规则,来合理的使用纯函数式的编程,这样我们的代码会更加的优雅。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 了解 JavaScript 函数式编程 - 声明式函数
- 了解 JavaScript 函数式编程 - 柯里化
- 了解 JavaScript 函数式编程-类型签名
- 想要确保架构目标达成?适合度函数了解一下
- 了解 JavaScript 函数式编程 - 代码组合的优势
- 了解递归的几种姿势 - 函数式编程
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。