JS函数式编程

1.为什么要学函数式编程

1.函数式编程事随着react 的流行受到越来越多的关注
2.Vue3 也开始使用函数式编程
3.函数式编程可以抛弃this
4.打包过程中可以更好的利用 tree shanking 过滤无用代码
5.方便测试,使代码更灵活,重复使用函数
6.很多库帮助我们进行函数式开发 lodash randa等

2.什么事函数式编程

函数式编程(Function Programming, FP) FP 是编程的范式之一

  • 面向对象编程的思维方式: 把现实世界的事物抽象成 => 程序世界中的类和对象,通过封装,继承和多态来演示事物和事物之间的联系
  • 函数式编程的思维方式:把现实世界的事物和事物之间的 联系 抽象到程序世界
	// 非函数式
	let num1 = 1
	let num2 = 2
	let sum = num1 + num2
	console.log(sum)
	
	// 函数式
	function add (n1, n2) {
		return n1 + n2
	}
	let sum = add(1, 2)
	console.log(sum)

3.函数是一等公民

  • 函数可以存储在变量中
  • 函数可以作为参数
  • 函数可以作为返回值
	// 1.函数作为变量中**
		let fn = function() {
			console.log('Hello')
		}
		let obj = {
			fn: views.fn
		}
	
	// 2.函数作为参数**
		let arr = [1, 2, 3, 4, 5]
		
		// 案例 1
		function forEach(arr, fn) {
			for (let i = 0; i < arr.length; i++) {
				fn(arr[i])
			}
		}
		forEach(arr, function(item) {
			console.log(item) // 1, 2, 3, 4, 5
		})
		
		// 案例 2
		function filter(arr, fn) {
			let result = []
			for (let i = 0; i < arr.length; i++) {
				if (fn(arr[i])) result.push(arr[i])
			}
			return result
		}
		let results = filter(arr, (item) => {
			return item % 2 === 0
		})
		console.log(results) // [2, 4]

	// 3.函数作为返回值**
		function once(fn) {
			let done = false
			return function() {
				if(!done) {
					done = true
					return fn.apply(this, arguments)
				}
			}
		}
		let run = once(() => {
			console.log('只执行一次')
		})
		run()
		run()
		run()

4.高阶函数的意义

  • 代码简洁,灵活
  • 可以帮我们屏蔽实现的细节

5.常用的高阶函数

  • forEach
  • map
  • filter
  • every
  • some

6.闭包

  • 函数嵌套函数,内部函数可以访问外部函数的参数和变量
  • 闭包可以延长外部函数内部变量作用范围
  • 内部函数未被调用时会内存不会被释放 ,从而产生垃圾
	function checkAge(min) {
		return function(age) {
			return min >= age
		}
	}

7.纯函数

  • 相同的输入始终得到相同的输出

  • 优势:
    1.值可以被缓存
    2.让测试更方便(如:单元测试断言函数的结果)
    3.并行处理 在多线程的环境下并行操作共享的数据(es6 (web worker)可以开启多线程)

  • 副作用:
    如果函数依赖外部的状态,无法保证输出相同

    let mini = 18 
    function (age) {
    	return age >= mini
    }
    age(20) => true
    
    let mini = 21
    age(20) => false
    
// 纯函数 / 不纯函数
	// 纯函数
	let array = [1, 2, 3, 4, 5]
	array.slice(0, 3)[1, 2, 3]
	array.slice(0, 3)[1, 2, 3]
	array.slice(0, 3)[1, 2, 3]
	
	// 不纯的函数
	array.splice(0, 3)[1, 2, 3]
	array.splice(0, 3)[4, 5, ]
	array.splice(0, 3)[]

	// 纯函数
	function getSum(n1, n2) {
		return n1 + n2
	}
	getSum(1, 2) => 3
	getSum(1, 2) => 3
	getSum(1, 2) => 3
	getSum(1, 2) => 3

8.*函数柯里化

  • 当一个函数是多个参数只接收部分参数,并返回一个新的函数,来接收剩余参数 (把多元函数转换为一元函数)
  • 可以把参数缓存起来
	// 演示
	// function checkAge(age) { // 硬编码
	//	 let min = 18
	//	 return age >= min
	// }
	
	// 普通的纯函数
	// function checkAge(min, age) {
	//	return age >= min
	// }
	// console.log(checkAge(18, 20))
	// console.log(checkAge(18, 24))
	// console.log(checkAge(22, 24))
	
	// 函数柯里化
	function checkAge(min) {
		return function(age) {
			return age >= min
		}
	}
	// es6 箭头函数
	let checkAge = min => (age => age >= min)
	
	let checkAge18 = checkAge(18)
	let checkAge20 = checkAge(20)
    checkAge18(20)
    checkAge20(22)
	
	// lodash 柯里化原理
	function getSum(a, b, c) {
		return a + b + c
	}
	function curry(func) {
		return function curryFn(...args) {
			// 判断实参和形参的个数

			// 实参 < 形参
			if (args.length < func.length) {
				return function() {
					return curryFn(...args.concat(Array.from(arguments)))
				}
			}
			// 实际参数大于 等于形参
			return func(...args)
		}
	}
	curry(getSum)(1, 2, 3) // 6
	curry(getSum)(1)(2, 3) // 6
	curry(getSum)(1)(2)(3) // 6

9.函数组合(函数组合默认从右到左执行)

  • 如果一个函数要经过多个函数处理才能得到最终值,这个时候可以把中间过程合并成一个函数
  • 函数组合可以让我们把细粒度的函数重新组合新的函数
	function compose(fn1, fn2) {
		return function(value) {
			return fn1(fn2(value))
		}
	}
	
	// 获取数组最后一个元素
	function reverse(array) {
		return array.reverse()
	}
	function first(array) {
		return array[0]
	}
	const last = compose(first, reverse)
	last([1, 2, 3, 4]) => 4
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值