纯函数和lodash

纯函数

相同的输入永远会得到相同的输出,而且没有任何可观察的副作用。

  • 纯函数类似于数学中的函数(用来描述输入和输出之间的关系),y=f(x);
    image

lodash

  • 是一个纯函数的功能库,提供了对数组、数组、数字、对象、字符串、函数等操作的一些方法
  • 数组的slice和splice分别是:纯函数和不纯的函数
    • slice 返回数组中的指定部分,不会改变原数组。
    • splice 对数组进行操作返回该数组,会改变原数组。
//纯函数和不纯的函数
//slice /splice

let array=[1,2,3,4,5];

//纯函数
console.log(array.slice(0,3));
//[1,2,3]
console.log(array.slice(0,3));
//[1,2,3]
console.log(array.slice(0,3));
//[1,2,3]

//不纯的函数
console.log(array.splice(0,3));
//[1,2,3]
console.log(array.splice(0,3));
//[4,5]
console.log(array.splice(0,3));
//[]

//相同的输入始终获取到相同的输出
//纯函数
function getSum(n1,n2){
return n1+n2;
}
console.log(getSum(1,2));
console.log(getSum(1,2));
console.log(getSum(1,2));
  • 函数式编程不会保留计算中间的结果,所以变量是不可变的(无状态的)
  • 我们可以把一个函数的执行结果交给另一个函数去处理

Lodash

Lodash 是一个一致性、模块化、高性能的 JavaScript 实用工具库。

安装lodash

初始化package.json:
npm init -y
安装lodash:
npm i lodash

//演示lodash
//first /last /toUpper /reverse /each /includes /find/findIndex
//定义常量引入lodash
const _=require('lodash');

//定义数组
const array=['jack','tom','lucy','kate'];

console.log(_.first(array));
console.log(_.last(array));

console.log(_.toUpper(_.first(array)));

console.log(_.reverse(array));//不是纯函数

const r=_.each(array,(item,index)=>{
	console.log(item,index);
})
console.log(r);

纯函数的优点

  • 可缓存
    • 因为纯函数对相同的输入始终有相同的结果,可以把纯函数的结果缓存起来
    • 能够提高代码的性能
//记忆函数
const _=require('lodash');
function getArea(r){
	console.log(r);
	return Math.PI*r*r;
}
let getAreaWithMemory=_.memoize(getArea);
//传入半径
console.log(getAreaWithMemory(4));
console.log(getAreaWithMemory(4));
console.log(getAreaWithMemory(4));
//并没有打印多次r
const _=require('lodash');
function getArea(r){
	console.log(r);
	return Math.PI*r*r;
}
模拟memoize方法的实现
function memoize(f){
	let cache={};
	return function(){
		let key=JSON.stringify(arguments);
		cache[key]=cache[key]||f.apply(f,arguments);
		return cache[key];
	}
}
let getAreaWithMemory=memoize(getArea);
console.log(getAreaWithMemory(4));
console.log(getAreaWithMemory(4));
console.log(getAreaWithMemory(4));
  • 可测试
    • 纯函数让测试更方便
  • 并行处理
    • 在多线程环境下并行操作共享的内存数据很可能出现意外情况(操作全局变量)
    • 纯函数不需要访问共享的内存数据,所以在并行环境下可以任意运行纯函数(Web Worker);

副作用

//不纯的
let mini=18;
function checkAge(age){
  return age>=mini;
}

//纯的(有硬编码,后续可以通过柯里化解决)
function checkAge(age){
  let mini=18;
  return age>=mini;
}

副作用让一个函数变得不纯,纯函数根据相同的输入返回相同的输出,如果函数依赖于外部的状态就无法保证输出相同,就会带来副作用。(例如全局变量)
副作用来源:

  • 配置文件
  • 数据库
  • 获取用户的输入
  • ...
    所有的外部交互都有可能带来副作用,副作用也使得方法通用性下降不适合扩展和可重用性,同时副作用会给程序中带来安全隐患给程序带来不确定性,但是副作用不可能完全禁止,尽可能控制它们在可控范围内发生。
posted @ 2021-12-28 14:52  flyall  阅读(104)  评论(0)    收藏  举报