纯函数 是一个常见的概念,在平常工做中也常常会遇到,它其实很是简单,今天咱们来了解一下它的好处以及为何要使用它。git
一个函数,若是符合如下两个特色,那么它就能够称之为 纯函数:编程
咱们先来看一个不纯的反面典型:api
let greeting = 'Hello' function greet (name) { return greeting + ' ' + name } console.log(greet('World')) // Hello World
上面的代码中,greet('World')
,是否是永远返回 Hello World
? 显然不是,假如咱们修改 greeting
的值,就会影响 greet
函数的输出。即函数 greet
实际上是 依赖外部状态 的。缓存
那咱们作如下修改:ide
function greet (greeting, name) { return greeting + ' ' + name } console.log(greet('Hi', 'Savo')) // Hi Savo
将 greeting
参数也传入,这样对于任何输入参数,都有与之对应的惟一的输出参数了,该函数就符合了第一个特色。函数式编程
反作用的意思是,这个函数的运行,不会修改外部的状态。函数
下面再看反面典型:单元测试
const user = { username: 'savokiss' } let isValid = false function validate (user) { if (user.username.length > 4) { isValid = true } }
可见,执行函数的时候会修改到 isValid
的值(注意:若是你的函数没有任何返回值,那么它极可能就具备反作用!)测试
那么咱们如何移除这个反作用呢?其实不须要修改外部的 isValid
变量,咱们只须要在函数中将验证的结果 return
出来:ui
const user = { username: 'savokiss' } function validate (user) { return user.username.length > 4; } const isValid = validate(user)
这样 validate
函数就不会修改任何外部的状态了~
你可能听过 纯函数
有很多优势,若是你经手过各类难维护的函数,你就更应该考虑使用 纯函数
。
让咱们先用不纯的 greet
方法来作单元测试:
// jest 语法 describe('greet', function() { it('shows a greeting', function() { expect(greet('Savo')).toEqual('Hello Savo') }); });
若是咱们修改了 greeting
变量为 Hi
,上面的测试就会失败了,这本质上不该该发生。
那咱们若是换成纯函数版本的 greet
,全部都是那么天然~ 只须要修改单元测试中传入的参数便可!
纯函数能够根据输入来作缓存。实现缓存的是一种叫做 memorize
的技术。
下面的代码来自 Vue 源码:
/** * Create a cached version of a pure function. * 只适用于缓存 接收一个字符串为参数的 fn */ export function cached (fn) { const cache = Object.create(null) return function cachedFn (str) { const hit = cache[str] return hit || (cache[str] = fn(str)) } } /** * Capitalize a string. */ export const capitalize = cached((str) => { return str.charAt(0).toUpperCase() + str.slice(1) })
capitalize
即为缓存后的函数,若是屡次调用就会返回缓存后的值,从而节省计算资源,而这一切的前提都创建在传入 cached
中的那个函数为纯函数的基础上。
因为纯函数是自给自足的,它须要的东西都在输入参数中已经声明,因此它能够任意移植到任何地方。
而且纯函数对于本身的依赖是 诚实的,这一点你看它的 形参 就知道啦~正所谓 形参起的好,注释不用搞~(双押!)纯函数就是这么个正直的小可爱~
好啦,咱们已经大概了解了纯函数,它对于咱们写出良好代码有着重要的意义,同时也是函数式编程中的精髓。原本本篇是想单纯介绍纯函数的,可是想起来了柯里化 (curry) 也没有讲过,那么下次有机会就讲一讲柯里化吧~
We'll see!
本文首发于公众号:码力全开(codingonfire)
本文随意转载哈,注明原文连接便可,公号文章转载联系我开白名单就好~