纯函数
纯函数要符合以下条件:
1.如果是相同的输入一定会返回相同的输出
2.函数在执行过程中,不能产生副作用(在执行函数时,对调用函数产生了附加的影响,比如修改了全局变量,修改参数或者改变外部的存储)
举例:
let arr = [1,2,3]
arr.slice(0,1)// 是纯函数,没有对原数组进行任何操作,而是生成了一个新的数组
arr.splice(0,1)// 不是纯函数,因为更改了原数组,修改了全局变量
纯函数的优势
为什么纯函数在函数式编程中非常重要?
1.因为可以安心的编写和安心的使用
2.在写的时候保证了函数的纯度,只是单纯实现自己的业务逻辑即可,不需要关心传入的内容是如何获得的或者依赖其他的外部变量是否已经发生了修改
3.在用的时候,确认输入的内容不会被任意篡改,并且自己确定的输入,一定会有确定的输出
柯里化
是把接收多个参数的函数,变成接收一个单一参数(最初函数的第一个参数)的函数,并且返回接收余下的参数,而且返回结果的新函数的技术。
如果你固定某些参数,你将得到接收余下参数的一个函数。
只传递给函数一部分参数来调用它,让他返回一个函数去处理剩余的参数,这个过程就称之为柯里化
举例
// 未柯里化的函数
var add1 = (x,y,z) => x + y + z
console.log(add1(10,20,30))
// 柯里化处理的函数
var add2 = x => y => z => x + y + z
console.log(add2(10)(20)(30))
柯里化让函数的职责单一
// 未柯里化的函数
function result(x,y,z){
x = x + 2
y = y * 2
z = z * z
return z + y + z
}
console.log(result(10,20,30))
// 柯里化处理的函数
function result2(x){
x = x + 2
return function(y){
y = y * 2
return function(z){
z = z * z
return z + y + z
}
}
}
console.log(result2(10)(20)(30))
柯里化的复用
function makeAdder(num) {
return function(count) {
return num + count
}
}
var add3 = makeAdder(5)
console.log(add3(10))
console.log(add3(100))
var add4 = makeAdder(10)
console.log(add4(10))
console.log(add4(100))
function log(date, type, message){
console.log(`[${date.getHours()}:${date.getMinutes()}][${type}][${message}]`)
}
console.log(log(new Date(),"DEBUG","修复问题"))
console.log(log(new Date(),"FEATURE","新功能"))
var log1 = date => type => message => {
console.log(`[${date.getHours()}:${date.getMinutes()}][${type}][${message}]`)
}
var debuge = log1(new Date())('DEBUG')
console.log(debuge('无效代码!'))
console.log(debuge('无效点击!'))
var warning = log1(new Date())('WARNING')
console.log(warning('警告代码!'))
console.log(warning('警告点击!'))
自动柯里化函数
function hyCurrying(fn) {
function curried(...args) {
if(args.length >= fn.length) {
return fn.apply(this, args)
}else{
return function(...args2) {
return curried.apply(this, args.concat(args2))
}
}
}
return curried
}
组合函数
理解
比如现在需要对都一个数据进行函数的调用,执行两个函数fn1和fn2,这两个函数是一次执行的;
那么如果我们每次都需要进行两个函数的调用,操作上就会显得重复;
那么是否可以将这两个函数组合起来自动依次调用呢?
这个过程就是对函数的组合,我们称之为组合函数。
function compose(fn1, fn2) {
return function(x) {
return fn2(fn1(x))
}
}
function double(num){
return num * 2
}
function square(num){
return num ** 2
}
var calcFn = compose(double,square)
console.log(calcFn(20))
实现组合函数
function compose(...fns) {
// 遍历所有的原生如果不是函数,那么直接报错
var length= fns.length
for (var i = 0; i < length; i++){
var fn =fns[i]
if (typeof fn !== 'function'){
throw new Typeerror('expected a function')
}
}
//取出所有的函数一次调用
return function(...args){
//先获取到第一次执行的结果
var index = 0
var result = length ? fns[index].apply(this, args) : args
while( ++index < length) {
result = fns[index].call(this, result)
return result
}
}