函数式编程 & 纯函数

什么是函数式编程?它跟纯函数的联系是什么?

函数式编程(Functional Programming,简称FP)是一种编程范式,它强调使用纯函数(Pure Functions)来解决计算问题。纯函数在函数式编程中扮演着关键角色,因为它们具有特定的属性和行为,使得函数式编程的原则和优点成为可能。

以下是函数式编程和纯函数之间的联系:

  1. 纯函数是函数式编程的基石:函数式编程的核心思想是使用纯函数来构建程序。纯函数是没有副作用的函数,其输出仅依赖于输入参数,不依赖于外部状态或变量。这种特性使得纯函数在函数式编程中成为可重用和可组合的构建块。

  2. 可缓存性(Cacheable):函数式编程强调数据不可变性,这意味着一旦数据被创建,就不能再被修改。纯函数与不可变性相辅相成。因为纯函数不修改输入,所以它们天然支持不可变性。在函数式编程中,不可变性有助于避免共享状态和副作用。

  3. 无状态性:纯函数没有内部状态,它们不维护任何外部状态。这与函数式编程的无状态原则相符,即程序的行为不依赖于历史状态,仅依赖于输入。

  4. 可测试性:纯函数易于测试,因为它们的行为完全取决于输入参数。在测试中,您可以提供不同的输入并验证输出是否符合预期,而无需担心外部状态的影响。

  5. 可组合性:纯函数具有良好的可组合性,因为它们不产生副作用。您可以将纯函数组合成更复杂的功能,而不会导致意外的行为。

  6. 引用透明性:纯函数是引用透明的,这意味着您可以用函数的结果替换函数调用,而不会改变程序的行为。这种特性有助于推导程序的性质和进行优化。

可缓存性(Cacheable)

纯函数的可缓存性是指,纯函数总能够根据输入来做缓存。实现缓存的一种典型方式是 memoize 技术。原理上只用把参数和对应的结果数据存到一个对象中,调用时,判断参数对应的数据是否存在,存在就返回对应的结果数据。

示例如下:

js 复制代码
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];
  };
};

var squareNumber  = memoize(function(x){ 
  console.log('计算',x)
  return x*x;
 });
var printWrap = function(x){return console.log(squareNumber(x))}

printWrap(4)

//=> 16

printWrap(4); // 从缓存中读取输入值为 4 的结果
//=> 16

printWrap(5);
//=> 25

printWrap(5); // 从缓存中读取输入值为 5 的结果
//=> 25

打印的结果:

可以看到相同输入的值只被计算了一次。

playground: playcode.io/1603378

什么是纯函数

纯函数的概念。

纯函数是这样一种函数,即相同的输入,永远会得到相同的输出,而且没有任何可观察的副作用。

比如 slicesplice,这两个函数都可以作为切割数组使用。但是他们各自实现的方式却大不相同 slice 符合 函数的定义是因为对相同的输入它保证能返回相同的输出。而 splice 却会改变调用它的那个数组,然后再返回;这就会产生可观察到的副作用,即这个数组永久地改变了

slice 创建一个新的数组,不会修改原始数组,根据指定的索引截取出一段连续的元素。

splice 修改原始数组,从指定的索引位置删除或添加元素,返回已删除的元素组成的新数组。

js 复制代码
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);
//=> []

总结

总之,函数式编程侧重于使用纯函数来构建程序,这些函数不依赖于外部状态、不产生副作用,并且易于测试和组合。这些特性使函数式编程具有可维护性、可测试性和可理解性的优点,并且有助于编写更安全和健壮的代码。纯函数是函数式编程的基本构建块,使函数式编程成为一种强大的编程范式。

参考

相关推荐
光影少年6 分钟前
vue2与vue3的全局通信插件,如何实现自定义的插件
前端·javascript·vue.js
As977_7 分钟前
前端学习Day12 CSS盒子的定位(相对定位篇“附练习”)
前端·css·学习
susu10830189119 分钟前
vue3 css的样式如果background没有,如何覆盖有background的样式
前端·css
Ocean☾10 分钟前
前端基础-html-注册界面
前端·算法·html
Rattenking11 分钟前
React 源码学习01 ---- React.Children.map 的实现与应用
javascript·学习·react.js
Dragon Wu13 分钟前
前端 Canvas 绘画 总结
前端
CodeToGym17 分钟前
Webpack性能优化指南:从构建到部署的全方位策略
前端·webpack·性能优化
~甲壳虫18 分钟前
说说webpack中常见的Loader?解决了什么问题?
前端·webpack·node.js
~甲壳虫22 分钟前
说说webpack proxy工作原理?为什么能解决跨域
前端·webpack·node.js
Cwhat24 分钟前
前端性能优化2
前端