函数进阶

1. 函数防抖

防抖代码实现

  // 使用setTimeout实现函数防抖
  var t = null;
  document.onmousemove = function (){
    // 每次移动之前清除先前计时器
    clearTimeout(t);
    t = setTimeout(() => {
      // 等待300毫秒后执行打印语句
      console.log('鼠标移动停止300毫秒打印');
    }, 300);
  }

防抖应用场景

一些高频率事件 在被连续多次触发时 只需生效一次


2. 函数节流

节流代码实现

  // 利用 状态 概念
  var t = null;
  document.onmousemove = function (){
    // 当计时器处于开启状态 不再重新开启新计时器
    if(t) return;
    t = setTimeout(() => {
        console.log("函数节流每300毫秒触发一次");
        t = null;
    }, 300);
  }

节流应用场景

一些高频率事件 间隔一段时间运行一次 被连续多次触发如果处于间隔时间内无效


3. 闭包函数

闭包函数的创建

  // 立即执行函数使fn得到return返回值
  const fn = (function(){
    let a = 10;
    return function(){
      return a;
    }
  })()
  // fn返回值为函数 加上()调用函数得到此函数return值
  console.log(fn());  // 10

闭包函数的应用

  const divs = document.querySelectorAll("div");

  // 添加了错误索引
  for(var i = 0; i < divs.length; i++){
    divs[i].onclick = function(){
      // 因为异步原因 执行点击事件时 i已经为最大值
      console.log(i);
    }
  }

  // 添加了正确索引
  // 方法一
  for(var  i= 0; i < divs.length; i++){
    ;(function(i){
      divs[i].onclick = function(){
        console.log(i);
      }
    })(i);
  }

  // 方法二
  for(var i = 0; i < divs.length; i++){
    divs[i].onclick = (function(i){
      return function(){
        console.log(i);
      }
    })(i);
  }

  // 方法三
  for(let i=0;i<divs.length;i++){
    divs[i].onclick = function(){
      console.log(i);
    }
  }

沙箱模式

  function outer() {
    let a = 10;
    let str = 'hello world';

    // 返回一个对象
    return {
      // 对每个私有变量都准备两个函数:get用来获取,set用来修改
      getA () { return a },
      setA (val) { a = val },
      getStr (val) { return a },
      setStr: function (val) { a = val }
    }
    // 使用数据劫持中getter和setter优化
    // return {
    //   get A() {return a}
    //   set A(val) {a = val}
    //   get Str() {return str}
    //   set Str(val) {str = val}
    // }
  }

4. 函数柯里化(Curring)

  function fn1(a, b){
    return a + b
  }

  function fn2(a) {
    return function (b) {
      return a + b
    }
  }
  fn1(1, 2) // 3
  fn2(1)(2) // 3
  // 解析
  // fn2(1) 返回function(b) {return a + b} 并且这个返回的函数能访问到第一次传入的值1 并且 值1生命周期没有结束 fn2(1)(2)返回a + b = 3
04-25 12:17