一、函数式编程的出现
发展历程: 命令(脚本)式 => 面向对象式 => 函数式
1、面试题
1、数组在url中展示的形式是什么?
location.search = "?arr[]=code$%1&arr[]=code$%2&arr[]=code$%3"
2、如何将字符串转换为数组?
['code$%1', 'code$%2', 'code$%3']
3、转换成对象
[{arr: 'code 1'}, {arr: 'code 2'}, {arr: 'code 3'}]
const arr = ['code$%1', 'code$%2', 'code$%3'];
const objArr = [];
arr.forEach(item => {
let newObj = item.split('$%')[0] + item.split('$%')[1];
objArr.push({arr: newObj})
})
方法拆分:
1、拆分字符串 => arr.split('$%')
2、组装字符串并且首字母大写 => _objArr.map(item => {
return item[0].toUpperCase() + item.slice(1)
})
3、组装对象 => objArr.map(item => {
return {arr: item}
})
二、函数式编程原理特点
1、函数式原理
- 函数式编程的核心思想是:将函数作为参数传递给另一个函数,然后由另一个函数调用该函数,从而实现对数据的处理。
2、理论思想
函数(一等公民)=> 1、逻辑功能最终实现 2、实现函数 与 流程拼接
声明式编程 => 声明需求 - 更贴近语言习惯
惰性执行(惰性函数)=> 衔接型,性能节约 (惰性函数表示函数执行的分支只会在函数第一次调用的时候执行)
const inertiaFn = val => {
if(val == 'fn1') {
return ineriaFn = () => {
console.log('fn1')
}
}else if(val == 'fn2') {
return ineriaFn = () => {
console.log('fn2')
}
}else {
return ineriaFn = () => {
console.log('fn3')
}
}
}
inertiaFn('fn1')()
3、无状态与无副作用 -- 纯函数
- 无状态:数据不可变 - 不可因为外界的调用而改变能力功能;
- 无副作用:函数的内部不应该直接对整个系统中任何参数变量进行改动
三、实际开发
1、纯函数改造
const _class = {
name: 'code',
}
// 函数内部引入外部变量 -- 无状态
const fn = (obj) => {_class.name + ':' + obj};
// 直接修改输入参数 -- 无副作用
const fn1 = (obj,name) => {obj.name = name};
const fn2 = (obj,name) => {obj.name + ':' + name}; // 不依赖外部变量
const fn3 = (obj,name) => ({...obj, name}); // 未修改外部变量
fn2(_class, 'code');
fn3(_class, 'code1');
2、流水线组装 - 加工 & 组装
加工 - 科里化
- 科里化:将函数的参数进行拆分,将拆分后的函数进行组合,最终实现对函数的调用
// fn(x,y,z) => fn(x)(y)(z)
const sum = (x,y) => {
return x + y
}
sum(1,2)
const add = x => {
return y => {
return z => {
return x + y + z
}
}
}
const add1 = add(1);
add1(2)
// 体系 = 加工 + 组装,单个加工输入输出应该单值化 => 单元函数
const fetch = (methed ,url, params);
- 面试题:手写构造可拆分传参的累加函数 add(1)(2)(3)(4)
// 1、构造科里化的结构
// 2、输入 处理外层 agruments => 类数组处理
// 3、传入参数无限拓展 => 函数返回自身
// 4、主功能 => 累加
// 5、输出 支持从函数到产出转换
const addd = function() {
// let args = Array.prototype.slice.call(arguments)
let args = [...arguments];
let inner = function() {
args.push(...arguments);
return inner;
}
inner.toString = function() {
return args.reduce((a,b) => a + b);
}
return inner;
}
addd(1)(2)(3)(4)