函数式编程 & 纯函数

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

函数式编程(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);
//=> []

总结

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

参考

相关推荐
Мартин.8 分钟前
[Meachines] [Easy] Sea WonderCMS-XSS-RCE+System Monitor 命令注入
前端·xss
昨天;明天。今天。2 小时前
案例-表白墙简单实现
前端·javascript·css
数云界2 小时前
如何在 DAX 中计算多个周期的移动平均线
java·服务器·前端
风清扬_jd2 小时前
Chromium 如何定义一个chrome.settingsPrivate接口给前端调用c++
前端·c++·chrome
安冬的码畜日常2 小时前
【玩转 JS 函数式编程_006】2.2 小试牛刀:用函数式编程(FP)实现事件只触发一次
开发语言·前端·javascript·函数式编程·tdd·fp·jasmine
ChinaDragonDreamer2 小时前
Vite:为什么选 Vite
前端
小御姐@stella2 小时前
Vue 之组件插槽Slot用法(组件间通信一种方式)
前端·javascript·vue.js
GISer_Jing2 小时前
【React】增量传输与渲染
前端·javascript·面试
GISer_Jing2 小时前
WebGL在低配置电脑的应用
javascript
eHackyd2 小时前
前端知识汇总(持续更新)
前端