compose函数&pipe函数&柯里化函数&节流函数&防抖函数

compose函数 也就是复合函数 

const add = (x) => x + 10;

const multple = (y) => y * 10;

console.log(multple(add(10))); // 200

function compose() {
    const args = [].slice.call(arguments);
    return function(x) {
        if (!args.length) return x;
        if (args.length === 1) return args(x)
        // 从右往左执行 先支持add 再执行multple
        return args.reduceRight((res, fun) => fun(res), x)
    }
}

}

const cu = compose(multple, add);
console.log(cu(10)) // 200

pipe函数,管道函数

顺序是从左往右,将reduceRight换成reduce就可以了。

const add = (x) => x + 10;

const multple = (y) => y * 10;

console.log(multple(add(10))); // 200

function compose() {
    const args = [].slice.call(arguments);
    return function(x) {
        if (!args.length) return x;
        if (args.length === 1) return args(x)
        // 从右往左执行 先支持add 再执行multple
        return args.reduce((res, fun) => fun(res), x)
    }
}

}

const cu = compose(multple, add);
console.log(cu(10)) // 200

柯里化函数  

柯里化就是将一个接收多个参数的函数转化为一系列使用一个参数的函数的技术。实现的效果就是

// 观察上诉柯里化调用发现,它其实就是把参数都搜集起来了,每次调用搜集几个参数
// 当搜集的参数足够时执行主方法
const curry = (fn) => {
  // 先记录主方法原始的参数个数,fn.length就是函数接收的参数个数
  const parmasLength = fn.length;

  return executeFun = (...args) => {
    // 如果接收参数够了,执行主方法
    if(args.length >= parmasLength) {
      return fn(...args);
    } else {
      // 如果参数不够,继续接收参数
      return (...args2) => {
        // 注意executeFun接收的参数是平铺的,需要将数组解构
        return executeFun(...args.concat(args2));
      }
    }
  }
}

const curriedFun = curry((a, b, c) => [a, b, c])
// 现在看下结果

console.log(curriedFun(1)(2)(3)) // [1, 2, 3]
console.log(curriedFun(1, 2)(3)) // [1, 2, 3]
console.log(curriedFun(1, 2, 3)) // [1, 2, 3]

fun.length是函数接受的形参的个数,arguments.length是函数接受的实参的个数。

function curry() {
    console.log(1)
}

console.log(curry.length) // 0

function curry1(a) {
    console.log(1)
}
console.log(curry1.length) // 1

function curry2(a) {
    console.log(arguments.length) // 0
}
console.log(curry2.length) // 1
curry2()

注意,如果以es6剩余参数的方式,fun.length不包含剩余参数。

function curry3(a, b, ...reset) {
    console.log(arguments.length) // 5
    console.log(reset) // [ 3, 4, 8]
}
console.log(curry3.length) // 2
curry3(1, 2, 3, 4, 8)

函数防抖 debounce
原理:将若干函数调用合成为一次,并在给定时间过去之后,或者连续事件完全触发完成之后,调用一次(仅仅只会调用一次)

可以去看下阿里巴巴的搜索框,当我们一直输入的时候,不去请求,当我们输入停止的时候,立马去发送请求。这里用到了防抖。

  /* 
   * 防抖函数
   * @param {Function} fun 要执行的函数
   *
   * @param {number} delay 一般是毫秒 时间周期,两个函数触发的时间间隔在时间周期内,不执行 否则,执行
  */
 
debounce(fun, delay) {
    let timer
    return function(...args) {
      if(timer) {
        clearTimeout(timer)
      }
      // 只有滚动事件停止前最后一次触发的timer才会执行
      timer = setTimeout(()=>{
        fun.apply(this, args)
      },delay)
    }
  }
document.addEventListener('scroll', debounce(function(){
  console.log(0)
}, 1000))


函数节流 throttle
原理:当达到了一定的时间间隔就会执行一次;可以理解为是缩减执行频率

 

看下网易严选的搜索框,当我们一直在输入的时候,是每隔一段时间请求一次。这里用到的是节流。

 /**
   * 节流函数 一段时间执行一次
   * 
   * @param {Function} fun 
   * @param {number} delay 
   */
  throttle(fun, delay) {
    let previous = 0;
    return function(...args) {
      const now = +new Date();
      if(now - previous > delay) {
        fun.apply(this, args)
        previous = now
      }
      
    }
  }

数组的扁平化

const flat = (arr, depth, initVal) => {
  const startVal = initVal || [];
  return arr.reduce((prevRes, item) => {
    // 如果里层还是数组,递归调用自身
    if(Array.isArray(item) && depth > 1){
      return flat(item, depth - 1, prevRes);
    }else{
      return prevRes.concat(item);
    }
  }, startVal)
}

const arr = [1, 2, [3, 4], [5, 6, [7, 8]]];
const flatArr = flat(arr, 1); // 只扁平化一层

console.log(flatArr);

 

http://www.dennisgo.cn/Articles/JavaScript/MemoryManagement.html

你可能感兴趣的:(JavaScript专题)