理解Javascript的纯函数

文章目录
  1. 1. 前言
  2. 2. 正文
    1. 2.1. 什么是纯函数
    2. 2.2. 相同输入相同输出
    3. 2.3. 无副作用
    4. 2.4. 结论

前言

本文1015字,阅读大约需要3分钟。

总括: 本文讲解了Javascript中纯函数的概念,以及如何去书写和判断纯函数。

读书必专精不二,方见义理

正文

函数式编程是一种如今比较流行的编程范式,它主张将函数作为参数进行传递,然后返回一个没有副作用的函数,说白了,就是希望一个函数只做一件事情。

像Javascript,Haskell,Clojure等编程语言都支持函数式编程。

这种编程思想涵盖了三个重要的概念:

  • 纯函数;
  • 柯里化;
  • 高阶函数;

而这篇文章主要是想向大家讲清楚纯函数这个概念。

什么是纯函数

所谓纯函数,需要满足两个必要条件:

  • 相同输入相同输出。函数相同的输入应具有相同的输出,但输出内容可以和输入内容无关;
  • 无副作用。函数没有副作用,具体表现为不可对函数以外的内容产生影响,且不依赖外部数据;

相同输入相同输出

先看一个反例:

1
Math.random();

这行简单的代码是JS内置函数,函数返回一个随机数,这就是一个典型非纯函数的例子,调用该函数的时候每次返回的结果都不是固定的,也就是说相同的输入得不到相同的输出

再来看一个非纯函数的例子:

1
2
3
var arr = [1 ,2, 3, 4, 5, 6, 7, 8, 9];
arr.splice(0, 2); //  [1, 2]
arr.splice(0, 2); //  [3, 4]

如上代码我们定义了一个数组,然后调用splice方法,两次调用输入相同都是02。但输出不同,一次输出为[1, 2],一次输出为[3, 4]

再举一个纯函数的例子:

1
2
3
const getOne = () => 'one';
getOne(2); // 'one'
getOne(); // 'one'

上面简单的getOne函数就是一个纯函数,不管调用多少次getOne()一定能得到相同的输出'one'。即使传递了参数,如上调用getOne(2)不管调用多少次总能得到相同的输出'one'。这就是输出内容和输入内容无关的一种情况。

无副作用

先看一个有副作用的例子:

1
2
3
4
5
var obj = { a: 1 };
const add = (b) => {
return obj.a + b;
}
add(2);

如上例子,sum函数也满足相同输入有相同输出的条件,sum(2)不管调用多少次都有相同的输出3。但它不是一个纯函数,因为它的输出依赖了外部变量obj。重写一个输出不依赖外部变量的函数:

1
2
3
4
5
6
var obj = { o: 1 };
const add = (a, b) => {
obj.o++;
return a + b;
}
add(1, 2);

上例依然不是纯函数,因为在add函数中对obj进行了修改,也就是说它对函数以外的内容产生了影响,有副作用。

结论

判断一个函数是否是纯函数的通俗方法很简单,单独把这个函数复制粘贴到其它地方它依旧可以运行,并且输入同样的参数能得到固定相同的输出,那这个函数就是一个纯函数。为什么要写纯函数呢?因为纯函数“干净”,一个纯函数只干一件事情,所以不会产生不可预料的结果,说实在点就是不会产生一些莫名其妙的bug。另外,如果一个应用程序由纯函数组成,也有利于进行单元测试调试起来也能方便许多,如果你使用了webpack对tree-shaking也更友好。

能力有限,水平一般,欢迎勘误,不胜感激。


能力有限,水平一般,欢迎勘误,不胜感激。

订阅更多文章可关注公众号「前端进阶学习」,回复「666」,获取一揽子前端技术书籍

前端进阶学习

如果您觉得我的文章对您有用,请随意打赏。

您的支持将鼓励我继续创作!

人过留名,雁过留声
听听你的声音

回复 Username 留言: content x