纯函数
说明




意思是调用的函数不依赖外部的变量,比如调用foo(111) ,不管在哪里调用,return出来的都是一样的,而不是根据外部环境不一样导致不一样。

副作用见下,就是不能对外部产生影响

副作用


案例
var names = ["abc", "cba", "nba", "dna"]// slice只要给它传入一个start/end, 那么对于同一个数组来说, 它会给我们返回确定的值// slice函数本身它是不会修改原来的数组// slice函数本身就是一个纯函数var newNames1 = names.slice(0, 3)console.log(newNames1)console.log(names)// ["abc", "cba", "nba", "dna"]// splice在执行时, 有修改掉调用的数组对象本身, 修改的这个操作就是产生的副作用// splice不是一个纯函数var newNames2 = names.splice(2)console.log(newNames2)console.log(names)
修改对象属性,只能通过返回新对象的方式,不影响原对象
优势



===================
柯理化
说明


// 柯里化// 只传递 toUpOrLow() 这个函数的1个参数upOrLow来调用它,// 然后它返回另一个函数,来处理剩余参数strfunction toUpOrLow(upOrLow){if(upOrLow == "up"){return function(str){return str.toUpperCase()}}else if(upOrLow == "low"){return function(str){return str.toLowerCase()}}}console.log(toUpOrLow("up")("aBc")) // "ABC"console.log(toUpOrLow("low")("aBc")) // "abc"
某些情况可以通过箭头函数简化 
作用1:函数的职责单一

作用2:复用



转成柯理化
// 普通函数function log(date, type, message) {console.log(`[${date.getHours()}:${date.getMinutes()}][${type}]: [${message}]`)}// 柯里化函数的实现hyCurryingfunction hyCurrying(fn) {function curried(...args) {// 判断当前已经接收的参数的个数, 可以参数本身需要接受的参数是否已经一致了// 1.当已经传入的参数 大于等于 需要的参数时, 就执行函数if (args.length >= fn.length) {// fn(...args)// fn.call(this, ...args)return fn.apply(this, args)} else {// 没有达到个数时, 需要返回一个新的函数, 继续来接收的参数function curried2(...args2) {// 接收到参数后, 需要递归调用curried来检查函数的个数是否达到return curried.apply(this, args.concat(args2))}return curried2}}return curried}// 普通函数,转成柯理化var curryAdd = hyCurrying(add1)console.log(curryAdd(10, 20, 30))console.log(curryAdd(10, 20)(30))console.log(curryAdd(10)(20)(30))
使用场景
Vue源码,很多高级的库里面有用到,可以自己定制化一些实现(比如自定义渲染器),然后传入柯理化的函数,增加可拓展性
===================
组合函数
说明

两个函数
正常调用
组合调用
通用的组合函数
function fnCompose(...fns) {// 获取传入函数的数量var length = fns.length// 1、先判断传入的是不是函数for (var i = 0; i < length; i++) {if (typeof fns[i] !== 'function') {throw new TypeError("Expected arguments are functions")}}// 定义组合函数function compose(...args) {var index = 0// 调用第一个函数var result = length ? fns[index].apply(this, args): args// 如果还有其他函数,就依次调用while(++index < length) {result = fns[index].call(this, result)}return result}// 最后返回出去调用return compose}
