Javascript进阶——函数式编程思想

什么是函数式编程? 在学习函数式编程之前,我们先来了解一些与之相关的概念,以便于我们更好的理解函数式编程思想: 命令式编程 首先我们要明确的是什么是命令式编程,这是与函数式编程相对应的一种编程方式,在日常开发中,我们大多数使用命令式编程。命令式编程就是详细的命令机器怎么做来达到我们想要的结果。 举个例子: 有一个需求,将数组中的每一项元素乘以2,我们很容易写出以下代码(代码示例1),这就是典型的命令式编程: let multip2=(arr)=>{ let newArr=[]; for(let i=0; i{ return regValidate(value, /^(\+|-)?\d+(\.\d+)?$/ig); } 正确的使用纯函数可以保证更加高质量的代码,也是一种更加干净的编码方式 函数副作用 当调用函数时,除了返回函数值以外,还对主调用函数产生了附加的影响,比如更改了全局变量(函数外部的变量)或者修改了参数。 还是通过代码来说明: // 以下代码中,test函数里改变了外部变量a的值,调用test之后,再次使用a变量就具有不确定性了 // 这就是给程序带来了副作用 let a=10; let test=()=> a=a+1; test(); console.log(a); //11 函数副作用会给程序设计带来不必要的麻烦,给程序带来难以查找的错误,并且降低程序的可读性 纯函数是没有副作用的。 可变性和不可变性 可变性是指一个变量创建以后可以任意修改;不可变性是指一个变量一旦创建,就永远不会发生改变,不可变性是函数式编程的核心思想。 仍然是结合代码来解释: // 可变性,调用test方法后,data的属性值发生改变 let data={count:1}; let test=(data)=>{ data.count=2; } console.log(data.count);// 1 test(data); console.log(data.count);// 2 // 我们可以通过改造test函数,使得数据不发生改变 let test=(data)=>{ // 这里也可以通过扩展属性来深拷贝{...data}, 但是扩展属性只能深拷贝数组或对象的第一层 let newData=JSON.parse(JSON.stringify(data)); newData.count=2; } console.log(data.count);// 1 test(data); console.log(data.count);// 1 函数式编程 了解了前面的这些概念,我们再来看看函数式编程是怎么回事以及如何实现的吧。 “函数式编程是一种编程范式。它把计算当成是数学函数的求值,从而避免改变状态和使用可变数据。它是一种声明式的编程范式,通过表达式和声明而不是语句来编程。” 这是维基百科上对函数式编程的定义。 简单来说,就是将复杂的函数逻辑抽象出简单函数,将运算过程尽量写成一系列嵌套函数调用;将一个任务拆分成一系列最小颗粒的函数,通过组合的方式来完成任务,跟组件化的思想很类似。 与命令式相对,函数式编程本质上是一种声明式编程,我们在编码时只需要完成所需要功能的代码,无需关心其内部实现,唯一需要考虑的是在这些内部实现中是否会产生副作用。 函数式编程必须满足两个要求: 纯函数 数据不可变 我们用函数式编程思想,来将第一段代码(代码示例1)改造一下: let arr=[1,2,3,4]; let arrMap=(arr, fn)=>{ let newArr=[]; for(let i=0; iitem * 2; let product=arrMap(arr,multip2); // 如果有新需求,将数组中的元素变为字符串格式 // 我们只需要添加一个tostring的函数就可满足 let tostring= item=>item.toString(); const strArr=arrMap(arr, tostring); 总结 诚然,函数式编程思想远不止如此,仍然需要更加的深入探究和大量的实践。然而即使如上述粗浅的学习心得,我们也不难发现函数式编程可以带来以下好处: 代码简洁,通过使用大量函数,重用,减少了重复的代码,提高编码效率 提高代码可靠性,得益于纯函数,不依赖、也不会改变外界的状态 易于测试维护,每一个函数都可以被看做独立单元,很有利于进行单元测试和调试,以及模块化组合 可读性强,声明式编程方式更接近自然语言 虽然清楚了函数副作用的弊端,但在开发中我们也无法完全消除函数副作用,只能尽可能的减少函数副作用: 函数入口使用参数运算,而不去修改参数 函数内不去修改函数外部的变量 运算结果通过函数返回给外部 通过“依赖注入”的方式让函数变“纯”,将依赖的变量提取出来,通过参数传给函数

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):