前端深入理解JavaScript函数式编程

2023-09-14 21:45:00

 🎬 岸边的风:个人主页

 🔥 个人专栏 :《 VUE 》 《 javaScript 》

⛺️ 生活的理想,就是为了理想的生活 !

在这里插入图片描述

目录

引言

1. 什么是函数式编程?

2. 纯函数和不可变性

3. 高阶函数

4. 函数组合

5. 柯里化

6. 递归

7. 函数式编程的优势

8. 结语


 

引言

函数式编程(Functional Programming)是一种编程范式,它将计算机程序视为数学函数的组合,强调函数的纯粹性和不可变性。JavaScript作为一种多范式的语言,也支持函数式编程风格。本文将介绍JavaScript函数式编程的基本概念和特点,并通过代码示例来展示其实际应用。

1. 什么是函数式编程?

函数式编程是一种基于数学函数的编程范式,它强调将计算过程看作是数学函数的组合。函数式编程的核心思想是将程序分解为一系列函数的调用,而不是通过修改共享状态来改变程序的执行。函数式编程强调函数的纯粹性(Pureness)、不可变性(Immutability)和无副作用(No Side Effects)。

在JavaScript中,函数是一等公民,即函数可以作为值进行传递和操作。函数式编程利用这一特性,通过组合和操作函数来构建程序,而不是通过修改变量的值。

2. 纯函数和不可变性

纯函数是函数式编程的核心概念之一,它具有以下特点:

  • 函数的输出只由输入决定,不受外部状态的影响。
  • 函数对相同的输入始终返回相同的输出。
  • 函数没有副作用,即不修改外部状态。

纯函数的好处在于可测试性、可缓存性和可组合性。由于纯函数没有副作用,它们在并行执行和调试时更容易处理。

不可变性是函数式编程的另一个重要概念,它指的是数据一旦创建就不能被修改。在JavaScript中,对象和数组是可变的,但我们可以通过函数式编程的方式来实现不可变性。

const numbers = [1, 2, 3, 4, 5];

// 使用不可变性的方式将数组元素加倍
const doubledNumbers = numbers.map(num => num * 2);

console.log(numbers);        // 输出:[1, 2, 3, 4, 5]
console.log(doubledNumbers); // 输出:[2, 4, 6, 8, 10]

在上述示例中,通过使用map()方法和箭头函数,我们创建了一个新的数组doubledNumbers,而不是直接修改原始的numbers数组。这种不可变性的操作确保了数据的纯粹性,避免了副作用。

3. 高阶函数

高阶函数是指接受一个或多个函数作为参数,并/或返回一个新的函数的函数。高阶函数是函数式编程的重要工具,它可以将函数作为数据进行操作和组合。

// 高阶函数示例:map()
function map(fn, array) {
  const result = [];
  for (let i = 0; i < array.length; i++) {
    result.push(fn(array[i]));
  }
  return result;
}

// 使用高阶函数map()对数组元素进行加倍
const numbers = [1, 2, 3, 4, 5];
const doubledNumbers = map(num => num * 2, numbers);

console.log(doubledNumbers); // 输出:[2, 4, 6, 8, 10]

在上述示例中,我们定义了一个高阶函数map(),它接受一个函数和一个数组作为参数,对数组的每个元素应用给定的函数,并返回一个新的数组。

高阶函数能够提高代码的复用性和可读性,通过将函数作为参数传递,我们可以将通用的操作抽象为一个函数,并在需要时进行调用。

4. 函数组合

函数组合是将多个函数组合为一个新函数的过程。函数组合可以通过将一个函数的输出作为另一个函数的输入来实现。

// 函数组合示例
function add(x) {
  return x + 2;
}

function multiply(x) {
  return x * 3;
}

function compose(f, g) {
  return function(x) {
    return f(g(x));
  }
}

const composedFunction = compose(multiply, add);
console.log(composedFunction(5));  // 输出:21 (5 + 2) * 3

在上述示例中,add()multiply()是两个简单的函数,compose()函数将这两个函数组合为一个新的函数composedFunctioncomposedFunction首先将输入值传递给add()函数进行加法操作,然后将结果传递给multiply()函数进行乘法操作。

函数组合使得代码的逻辑更加清晰和简洁,可以将复杂的操作分解为一系列简单的函数,并按照特定的顺序进行组合。

5. 柯里化

柯里化(Currying)是一种将接受多个参数的函数转换为一系列接受单个参数的函数的技术。柯里化通过创建一个接受部分参数的新函数,并返回一个接受剩余参数的新函数来实现。

// 柯里化示例
function add(x) {
  return function(y) {
    return x + y;
  }
}

const add2 = add(2);
console.log(add2(3));  // 输出:5

在上述示例中,我们定义了一个函数add(),它接受一个参数x并返回一个新的函数。返回的函数

接受另一个参数y,并返回x + y的结果。通过使用柯里化,我们可以通过传递部分参数来创建新的函数,并在需要时传递剩余的参数。

柯里化使得函数的复用更加灵活和方便,可以根据需要进行参数的组合和传递。

6. 递归

递归是函数式编程中常用的一种技术,它通过函数自身的调用来解决问题。递归函数包含两个部分:基本情况(Base Case)和递归调用(Recursive Call)。

// 递归示例:计算阶乘
function factorial(n) {
  if (n === 0) {
    return 1;  // 基本情况
  } else {
    return n * factorial(n - 1);  // 递归调用
  }
}

console.log(factorial(5));  // 输出:120

在上述示例中,我们定义了一个递归函数factorial()来计算阶乘。当n等于0时,递归函数达到了基本情况,返回1;否则,函数将调用自身并传递n - 1作为参数。

递归使得问题的解决方式更加自然和简洁,可以用更少的代码实现复杂的问题。

7. 函数式编程的优势

函数式编程具有许多优势,包括:

  • 可读性:函数式编程强调函数的纯粹性和不可变性,使得代码更易于理解和推理。
  • 可测试性:纯函数和不可变数据使得单元测试更加简单和可靠。
  • 并行执行:函数式编程避免了共享状态和副作用,使得程序更容易进行并行执行。
  • 可扩展性:函数式编程通过函数的组合和高阶函数的使用,使得代码的复用和扩展更加方便。

函数式编程风格提供了一种新的思考方式和编程范式,它强调函数的纯粹性、不可变性和无副作用,使得代码更加清晰、可读性更高,并具有更好的可测试性和可扩展性。

8. 结语

本文介绍了JavaScript函数式编程风格的基本概念和特点,并通过代码示例展示了纯函数、不可变性、高阶函数、函数组合、柯里化、递归等函数式编程的实际应用。函数式编程提供了一种新的思考方式和编程范式,可以使我们的代码更具可读性、可测试性和可扩展性。

更多推荐

提升预算管控精度,助力保险资管协会财务管理数字化转型

数字化转型是当前中国经济社会发展的重要趋势和根本方向。中国保险资产管理业协会(以下称“协会”)是专门履行保险资产管理自律职能的全国性金融自律组织。过去几年,协会一直在积极探索应用信息化手段,加强预算管理。近期,协会与百望云合作,重构了预算项目,整合了核算、报销、OA系统,通过智能管票、系统控制,搭建全流程自动化、智能化

为什么我们总是被赶着走

最近发生了一些事情,让shigen不禁的思考:为什么我们总是被各种事情赶着走。一第一件事情就是工作上的任务,接触的是一个老系统ERP,听说是2018年就在线上运行的,现在出现问题了,需要我去修改一下。在这里,我需要记录一下技术背景:ERP系统背景后端采用的是jfinal框架,让我觉得很奇葩的地方有:接受前端的参数采用的

HDFS的Shell操作

1、进程启停管理1.1、一键启停脚本HadoopHDFS组件内置了HDFS集群的一键启停脚本。1.1.1、一键启动HDFS集群$HADOOP_HOME/sbin/start-dfs.sh,一键启动HDFS集群start-dfs.sh执行原理:在执行此脚本的机器上,启动SecondaryNameNode。读取core-s

GIT常用命令

GIT常用命令1、版本控制!什么是版本控制版本迭代,新的版本!版本管理器版本控制(Revisioncontrol)是一种在开发的过程中用于管理我们对文件、目录或工程等内容的修改历史,方便查看更改历史记录,备份以便恢复以前的版本的软件工程技术。实现跨区域多人协同开发追踪和记载一个或者多个文件的历史记录组织和保护你的源代码

聊聊编程是什么

前言前言不看没关系,不影响。半夜睡不着,想写点啥,浅聊下我理解的编程的,我认为编程就是解决问题,就像互联网是依附于实体业,是处理解决实际问题的。刚学编程的时候总是很恐慌的,天赋不够,我这么认为的原因,一是当时流行一种说法叫不是热爱编程的是坚持不下去或者没什么发展的,后来发现是一些阴谋家为了减少竞争的言论;二是确实遇上了

Axios笔记

1、Axios介绍Axios基于promise网络请求库,作用于node.js和浏览器中(即同一套代码可以运行在node.js和浏览器中),在服务器中他使用原生node.jshttp,在浏览器端则使用XMLHttpRequest。特性:(1)、支持PromiseAPI(2)、拦截请求和响应、转换请求和响应数据、取消请求

Java手写启发式搜索算法和启发式搜索算法应用拓展案例

Java手写启发式搜索算法和启发式搜索算法应用拓展案例1.算法思维导图以下是使用Mermanid代码表示的启发式搜索算法的实现原理:#mermaid-svg-3nox60fbtHCDRqqD{font-family:"trebuchetms",verdana,arial,sans-serif;font-size:16p

免费好用bpm平台,实现生产管理系统

1.什么是生产管理系统生产制造管理系统主要是以生产制造管理为核心,其管理功能包括产品结构设置(BOM)生产计划、加工、领料、质检、库存、成本核算等。通过信息化解决行业管理问题,满足各企业科学管理的需求,并为制造管理提供较完善的解决方案。2.为什么选择天翎市面上不乏各种成品软件可供企业选择,但成品软件多数为通用固定的功能

Shell 正则表达式及综合案例及文本处理工具

目录一、常规匹配二、常用特殊字符三、匹配手机号四、案例之归档文件五、案例之定时归档文件六、Shell文本处理工具1.cut工具2.awk工具一、常规匹配一串不包含特殊字符的正则表达式匹配它自己例子,比如说想要查看密码包含root字符串的,可以这样写cat/etc/passwd|greproot二、常用特殊字符特殊字符作

【跟小嘉学 Rust 编程】三十二、Rust的设计模式(Design Patterns)

系列文章目录【跟小嘉学Rust编程】一、Rust编程基础【跟小嘉学Rust编程】二、Rust包管理工具使用【跟小嘉学Rust编程】三、Rust的基本程序概念【跟小嘉学Rust编程】四、理解Rust的所有权概念【跟小嘉学Rust编程】五、使用结构体关联结构化数据【跟小嘉学Rust编程】六、枚举和模式匹配【跟小嘉学Rust

K8S:pod集群调度及相关操作

文章目录一.pod集群调度概念1.调度约束(List-Watch组件)2.List-Watch的工作机制(1)List-Watch的工作机制流程(2)List-Watch的工作机制图示3.调度的过程(1)调度的任务(2)调度选择pod节点(3)调度的过程(4)调度的算法(5)调度的优先级二.pod集群调度示例1.指定调

热文推荐