1.纯函数的定义
函数在相同的输入时,产生相同的输出
函数在执行过程中,不产生副作用
比如触发事件,使用输出设备输出,或者更改输出值以外的物件的内容等等
什么是副作用呢?
side effect(副作用)表示在执行一个函数的时候,除了返回函数值之外,还对调用函数产生了附加的影响,比如修改了全局变量,修改参数或者改变外部的存储
纯函数在执行过程中就是不能产生这样的副作用,因为副作用往往是产生bug的温床
var names = ['zb', 'sh', 'ss']
// var newArr = names.slice(0, 2)
// slice本身就是一个纯函数,因为返回了一个新的数组,并没有改变原来的数组
// slice 的实现
Array.prototype.zbslice = function(start, end) {
fn = this
let newArr = []
// start = start || 0
start = start === undefined ? 0 : start
// end = end || fn.length
end = end === undefined ? fn.length : end
for (let i = start; i < end; i++) {
newArr.push(fn[i])
}
return newArr
}
// console.log(newArr);
console.log(names.zbslice(0, 2));
2.js柯里化
是吧接受多个参数的函数u,变成接受一个单一的参数(最初函数的第一个参数)的函数,并且返回接收余下的参数,而且返回结果的新函数的技术
只传递给函数一部分的参数来调用它,让他返回一个函数去处理剩余的参数
这个过程就叫做柯里化
function sum(a, b, c, d) {
return a + b + c + d
}
// 平常的调用是这样的
let sum1 = sum(10, 20, 30, 40)
console.log(sum1);
// 下面的样子就是函数柯里化
function s(a) {
return function(b) {
return function(c) {
return function(d) {
return a + b + c + d
}
}
}
}
let res = s(10)(20)(30)(40)
console.log(res);
3.柯里化的作用
在函数式编程中,我们其实希望一个函数处理的问题尽可能的单一,而不是将一大堆的处理过程交给一个函数来处理
那么我们是否就可以将每一次传入的参数在单一的函数中处理,处理完成以后在下一个函数中再次使用处理后的结果
也就是单一职责原则
// 下面的样子就是函数柯里化
function s(a) {
a = a + 10
return function(b) {
b = b * 10
return function(c) {
c = c + 60
return function(d) {
return a + b + c + d
}
}
}
}
4.柯里化的逻辑的复用
function log(date, type, message) {
console.log(`[${date.getHours()}:${date.getMinutes()}][${type}]: [${message}]`)
}
// 柯里化的优化
var log = date => type => message => {
console.log(`[${date.getHours()}:${date.getMinutes()}][${type}]: [${message}]`)
}
// 如果我现在打印的都是当前时间
var nowLog = log(new Date())
nowLog("DEBUG")("查找到轮播图的bug")
nowLog("FETURE")("新增了添加用户的功能")
//能发现要执行某一个函数的时候,不用每次传入三个参数,只需要在你需要的功能那块输出即可,详细见下面的代码
var nowAndDebugLog = log(new Date())("DEBUG")
nowAndDebugLog("查找到轮播图的bug")
nowAndDebugLog("查找到轮播图的bug")
nowAndDebugLog("查找到轮播图的bug")
nowAndDebugLog("查找到轮播图的bug")
var nowAndFetureLog = log(new Date())("FETURE")
owAndFetureLog("添加新功能~")
拿函数的参数个数有以下方法
function sum(a,b,c,d,e,f)
直接使用 sum.length 求出的就是sum函数的参数长度
5.组合函数
function double(num) {
return num * 2
}
function square(num) {
return num ** 2
}
var count = 10
var result = square(double(count))
console.log(result)
// 实现最简单的组合函数
function composeFn(m, n) {
return function(count) {
return n(m(count))
}
}
var newFn = composeFn(double, square)
console.log(newFn(10))
6.实现组合函数
function zbCompose(...fns){
var length = fns.length
//先遍历传入的参数类型是否都是函数类型
for(let i = 0; i < length;i++){
if(typeof fns[i] !== 'function'){
throw new TypeError('传入的参数不是函数类型')
}
}
// 如果上面传入的参数都是函数的类型
// 那么我们就开始
function compose(...args){
var index = 0
let result = length ? fns[index].apply(this,args) : args
while(++index < length){
result = fns[index].call(this,result)
}
return result
}
return compose
}
\