闭包----防抖与节流

闭包: 函数嵌套函数,内部函数就是闭包;

体会闭包

  function outerfun(x){
            function innerfun(y){
                console.log(x + y);
            }
            return inner;  //没有小括号,表示只输出inner函数的定义,不会立即执行
        }
        var i = outerfun(3);
        /* 其实这个时候
        i = innerfun(y){
            console.log(3 + y)
        }
        */

        i(5);  //8

经典案例:

 function outer() {
            let a = 10;
            function inner() {
                console.log(a);
            }
            return inner;  //没有小括号,表示只输出inner函数的定义,不会立即执行
        }
        console.log(outer());  //inner函数
        var fun = outer();   //fun 内部存储的是inner函数的地址。
        /* 相当于function inner() {
            console.log(10)
        }*/
        fun()   //10

闭包: 内部函数没有执行完,外部函数的变量不会被销毁。

闭包的应用?
可以封装一段代码,模块化

 //原来的写法
        let a = 10;
        let b = 20;
        function add() {
            return a + b;
        };
        function sub() {
            return a - b;
        }
        let res1 = add();
        let res2 = sub();
        console.log(res1);
        console.log(res2)

封装后的写法:

  //  封装后的写法,模块化
        let module = (function () {   //自执行函数
            let a = 10;
            let b = 20;
            function add() {
                return a + b;
            };
            function sub() {
                return a - b;
            }
            return {
                //  add: add,
                //  sub: sub,
                add,  //es6的简写语法
                sub,
            }

        })()
        let res1 = module.add();
        let res2 = module.sub();
        console.log(res1);
        console.log(res2);

防抖: 用户触发时间过于频繁,只要最后一次事件的操作;
比较好理解但是很烂的代码哈哈哈,下面有封装好的代码;

    let ipt = document.querySelector("input");
    // ipt.oninput = function(){
    //     console.log(this.value);  //过于频繁触发
    // }
    // 定义一个全局的计时器time
    let time = null;
    ipt.onchange = function(){
        // 判断,time是计时器的返回值,如果time不是null,就清掉计时器;
        if(time !== null){
            clearTimeout(t);
        }
        t = setTimeout(()=>{
            console.log(this.value);
        }, 500)
    }

封装好的防抖代码:

 let ipt = document.querySelector("input");
        ipt.onchange = debounce(function(){
            // console.log("hello 防抖--闭包");
            console.log(this.value);    //使用 fn.call(this)后,这里的this指向发生改变
        }, 500)

        function debounce(fn, delay){
        let time = null;   // 定义一个计时器time
        return function(){
            // 判断,time是计时器的返回值,如果time不是null,就清掉计时器;
            if(time !== null){
                clearTimeout(t);
            }
            t = setTimeout(()=>{
                // console.log(this.value);  //这里的this指向input
                // fn();  // 
                fn.call(this);  //直接调用fn()即可,但是同时还要改变this的指向,所以使用fn.call(this); 
            }, delay)
        }
        }

节流:控制执行次数;
区别防抖:是只执行最后一次;
节流的现象:
给body标签设置,鼠标滚动一下,就会触发一次;

 <style>
        body{
            height: 50000px;
        }
    </style>
  window.onscroll = function(){
            console.log(124);
        }

控制节流的代码:

 // 节流: 控制执行次数
        // 最开始flag是true, if判断为true执行,执行一次后,设置为true,500毫秒执行一次;
        let flag = true
        window.onscroll = function(){
            if(flag) {
                setTimeout(()=>{
                    console.log(123);
                    flag = true;
                }, 500)
            } 
            flag = false;
        }

封装的节流代码:

 // 封装节流的代码
        window.onscroll = throttle(function(){
            console.log("hello");
        }, 500)
        function throttle(fn, delay){
            let flag = true
            return function(){
            if(flag) {
                setTimeout(()=>{
                    // console.log(123);
                    fn.call(this);
                    flag = true;
                }, delay)
            } 
            flag = false;
        }
        }

节流: 在一定的时间内,执行一
次,控制次数;
防抖: 高频发事件,只执行最后一次;

课程讲解:
https://www.bilibili.com/video/BV1E44y1z7XL
https://www.bilibili.com/video/BV1HK4y1g7fA
https://www.bilibili.com/video/BV1Qo4y1Q7AN/?spm_id_from=autoNext

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值