全栈之旅:javaScript 进阶 - 提高代码可靠性

77 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情

提高代码可靠性

函数式编程

函数式编程是种编程方式,它将电脑运算视为函数的计算。函数编程语言最重要的基础是λ演算(lambda calculus),而且λ演算的函数可以接受函数当作输入(参数)和输出(返回值)。 函数式编程的目的是把冗余的方法进行拆解,进而提高代码的利用率。

1.案例:对数组的每一项进行+1

let Arr = [ 1 , 2 , 3 , 4 ]
let NewArr = []
for(let i = 0 ; i < Arr.length ; i++){
  NewArr.push(Arr[i]+1)
}
console.log(NewArr) //  [ 2 , 3 , 4 , 5 ]

而这时,如果想要扩展算法(加任意数、做减法或者乘法),就可以使用函数式编程:

let addNum = ( num , anyNum=1 )=> num + anyNum
let multiPNum = ( num , anyNum=1 ) => num*anyNum
let resArr = (arr=[],fn,anyNum)=>{
let res = []
for(let i = 0 ; i < arr.length ; i++){
  res.push(fn(arr[i],anyNum))
  } 
return res 
}
let Arr = [ 1 , 2 , 3 , 4 ]
resArr( Arr , addNum , 2 ) // [ 3 , 4 , 5 , 6 ]
resArr( Arr , multiPNum , 2 ) // [ 2 , 4 , 6 , 8 ]

纯函数

既函数传参一致的情况下,得到的结果永远一致:

//纯函数
let chun = (any)=>{
console.log(any)
}
//非纯函数
let unchun = (any)=>{
console.log(`${any}---${new Date()}`)
}

函数副作用

  • 当调用函数时,除了返回函数值外,还对注调用函数产生附加的影响。
  • 例如修改全局变量(函数外的变量)或修改参数。
//函数外a被改变,这就是函数的副作用
let a = 5
let foo = () => (a = a * 10)
foo()
console.log(a) // 50

let arr = [1, 2, 3, 4, 5, 6]
arr.slice(1, 3) //纯函数,返回[2,3],原数组不改变
arr.splice(1, 3) // 非纯函数,返回[2,3,4],原数组被改变
arr.pop() // 非纯函数,返回6,原数组改变

而为了增加函数得可控制性,需要用参数的方式进行注入:

let a = 5
let foo = (num,des=1)=> num * des
foo(a,2) //10

函数副作用可变性和不可变性

  • 可变性是指一个变量创建以后可以任意修改
  • 不可变性指一个变量,一旦被创建,就永远不会发生改变,不可变性是函数式编程的核心概念
// javascript中的对象都是引用类型,可变性使程序具有不确定性,调用函数foo后,我们的对象就发生了改变;这就是可变性,js中没有原生的不可变性
let data = { count: 2 }
let foo = data => {
  data.count = 3
}
console.log(data.count) // 2
foo(data)
console.log(data.count) // 3

// 改进后使我们的数据具有不可变性
let data = { count: 2 }
let foo = data => {
  let deepData = JSON.parse(JSON.stringify(data)) // 做了一次伪深度克隆,将对象栈地址和堆数据进行复制
  deepData.count = 3
}
console.log(data.count) // 2
foo(data)
console.log(data.count) // 2