浅谈javascript之闭包


给搜索框添加一个属性,实现这个表单输入的时候,不会弹出记录框! -启用自动完成功能的表单(其中一个输入字段禁用了自动完成)

这边会使用到节流和去抖的知识:有兴趣的可以看这一篇文章
链接: link.

闭包

01:函数调用 => 产生一个新的执行环境
02:变量对象 => 用来存储代码执行之中的数据(就是变量对象)
注意点;window对象是一个持续存在的对象,负责存储全局环境下得所有变量和对象!
03:活动对象 => 变量对象只在函数活动期间存在
注意点:函数执行完毕后,这个被销毁的变量就是活动对象!

    function funA() {
      a = 100;
    }
    funA();
//在函数funA调用的时候,会创建一个执行环境,来存储函数funA执行时候创建的数据(比如这个a = 100),因此函数A也是有着自己的变量对象!
//但是这个变量对象在编译的时候存在,也就是说,在funA调用后,会创建一个变量对象a=100,当函数执行完毕的时候,就销毁了这个变量!
注意点:这个销毁的变量就是活动对象!

变量的概念

在函数内部返回一个匿名函数,在这个匿名函数之中引用这个变量。

  • 在闭包的情况下会产生一个特殊的变量(自由变量);
  • 全局变量 : 生命周期(永久) 可访问性( 在任意地方都可以被访问 )
  • 局部变量 : 生命周期 (函数执行结束立即删除) 可访问性 (仅在函数内部可以被访问)
  • 自由变量 : 生命周期 (永久) 可访问性 (仅在函数内部访问);

自由变量

  • 作用:
    • 01:在任意时间内被调用,不会被销毁!
    • 02:保证数据的隐私性 => 只有你的函数可以使用;
    var a = 100;
    function funA() {
      a = 100;
      return function () {
        //这个变量a在内部被使用到,也就是说,变量a不会被销毁!
        console.log(a);
      }
    }
    funA()
    //在函数内部返回一个匿名函数,在匿名函数内部引用这个变量a,匿名这个变量为自由变量!
            // 一个需求 : 
            // 1. 这是一个考试系统;
            // 2. 会把所有的数据发送给前端包括答案;
            // 3. 考试结束实时给予评分。(前端完成);

            // - 你答案放在哪里 ? 
            // 需求难点 :
            // 1. 请求一次返回所有数据  : 1. 答案  2. 试题;
            // 2. 答案这个东西考虑到我们需要在后面使用 , 我们是不是应该把这样的数据放在全局中那 ? 

            // 1 需要持久的保存数据;
            // 2 这个数据只有在我们的程序之中可以访问;

            // 伪代码 : 

            function load(){
                  // 请求之中会获取到试题和答案;
                  return $.ajax( {} )
            }
            
            load().then( function( data ){
                  // 答案
                  var ans = data.ans;
                  // 试题;
                  var que = data.que;

                  renderQue( que );

                  return function(){
                        // 使用 ans;
                        console.log(ans);
                  }
            })

闭包的作用1:

需求:点击ul中的li,输出对应的索引号

    //需求:使用闭包的方式,来点击当前的小li获取到当前的小li的索引号
    var lis = document.querySelectorAll("li");
    for (var i = 0; i < lis.length; i++) {
      //利用闭包的方式,把当前的i当做参数传递到立即执行函数内部,才出发当前的点击事件,打印对应的索引号!
      (function (num) {
        lis[i].onclick = function () {
          console.log(num);
        }
      })(i)

    }

闭包的作用2:封装函数

  • 1:节流函数的封装
    //需求:利用闭包的方式,封装一个用于节流和防抖的函数 
    //throttle --- 节流     antiShake ---防抖
    //节流的封装 
    // 参数1:回调函数(里面书写的是消耗性能方面的函数) 参数2:延迟时间 参数3:改变this的指向!
    function throttle(callback, delay, context) {
      var flag = true;
      delay = delay || 100;
      return function () { //产生闭包
        if (flag) {
          flag = false;
          setTimeout(function () {
            context ? callback.call(context) : callback();
            flag = true;
          }, 200)
        }
      }
    }
    // document.onscroll = throttle(function () {
    //   console.log("消耗性能的函数");
    // }, 200)
  • 2:封装一个去抖的函数
  //去抖的封装
    //参数1:回调函数 参数2:延迟时间 参数3:改变this的指向
    function antiShake(callback, delay, context) {
      var timer = "";
      var delay = delay || 100;
      return function () { //产生闭包
        clearInterval(timer)
        timer = setTimeout(function () {
          context ? callback.call(context) : callback();
        }, 200)
      }
    }
    // document.onscroll = antiShake(function () {
    //   console.log("消耗性能的2");
    // }, 200)
  • 3:把节流和去抖封装为一个函数
 // 封装一个节流和去抖的函数
    //参数1:节流还是去抖的方式(th-节流,ant-去抖)  参数2:回调函数(事件处理函数)
    //参数3:延迟时间  参数4:改变this的指向
    function funPerformance(type, callback, delay, context) {
      delay = delay || 100;
      flag = true;
      timer = "";
      return function () {
        switch (type) {
          //节流
          case "th":
            if (flag) {
              flag = false;
              setTimeout(function () {
                context ? callback.call(context) : callback();
                flag = true;
              }, 200)
            }
            break;
            //去抖
          case "ant":
            clearInterval(timer)
            timer = setTimeout(function () {
              context ? callback.call(context) : callback();
            }, 200)
            break;
        }
      }
    }

//调用的时候:
    document.onscroll = funPerformance("ant", function () {
      console.log("消耗性能的2");
      console.log(this); //这边的rhis指向的window ,所以要是使用到this的时候,我们可以在后面修改为前面的调用者
    }, 200, document)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值