闭包以及高频事件性能优化的两种方法(节流、防抖)

1 篇文章 0 订阅
1 篇文章 0 订阅

代码开发的格式 - 注意冲突和依赖
开发项目的时候有很多种写法,像模块化开发,命名空间,闭包…,闭包其实就是一种写法

闭包:它是JavaScript独有的一种函数结构(一种函数的嵌套用法)

闭包的形成与变量的作用域以及变量的生存周期密切相关,变量的作用域,就是指变量的有效范围。生存周期对于全局变量是永久的,除非我们主动销毁这个全局变量。而对于在函数内用 var 关键字声明的局部变量来说,当退出函数时,这些局部变量即失去了它们的价值,它们都会随着函数调用的结束而被销毁:

讲一下作用域链:
当声明一个函数时,局部作用域一级一级向上包起来,就是作用域链。
函数的内部有个[[scope]]的内部属性,它在函数创建的时候会有全局对象;函数执行的时候会有活动对象;为什么函数里的对象函数外获取不到呢?是因为函数在执行完,活动对象自行销毁

形成闭包的三个条件

  1. 函数嵌套
  2. 内层函数使用了外层函数的变量或参数
  3. 内层函数被返回到外部 在外部调用 ( 将内层函数作为返回值 )

闭包的作用

  1. 隔离作用域 避免作用域污染
  2. 保护具有共享意义的变量 为变量提供相关的操作接口

闭包的缺点

  1. 占用内层空间 大量使用闭包会造成 栈溢出
  2. 使用过于复杂

如何销毁闭包?
将闭包函数赋值为null 可以销毁闭包

实例:

function fn() {
            var num = 100;

            function fn2() {
                // 由于内层函数使用外层函数的变量
                // 并且内层函数被返回到外部
                // 导致局部变量引用未释放 (局部变量没有销毁)
                // 一直存在在内层中
                num += 50;
                console.log(num);
            }
            return fn2;
        }
        var fn2 = fn();
        fn2();//打印结果150
        fn2();//打印结果200

注意:自执行函数不是闭包,但是自执行函数可以达到闭包的效果,同时它也可以写成闭包

闭包函数的应用:

什么是高频事件?

高频事件 指的是 触发频率高的事件
例如oninput,onkeypress,onscroll,resize等事件触发频率非常高

高频事件性能优化-函数节流

核心思想:在连续触发的事件中,一定的时间内只执行一次我们的函数。

需要两个时间
第一个时间:上次的执行时间 ;
第二个时间:间隔时间
当前时间-上次执行时间 >= 2000ms

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #box {
            width: 300px;
            height: 300px;
            background-color: red;
        }
    </style>
</head>
<body>
    <div id="box"></div>
    <script>
        window.onload=function(){
            function fn(callback,wait){
                let prev=0;//  prev 用于记录上次执行的时间
                return function(){
                    let args=arguments;//参数
                    let now=Date.now();//获得当前时间
                    if(now-prev>=wait){
                        callback.apply(this,args);//修改this指向,传入形参
                        prev=now;// 将当前的时间记录为上一次的执行时间
                    }
                }
            }
        
            let box=document.getElementById('box');
            box.addEventListener('mousemove',fn(function(ev){
                console.log('执行了 move');
                console.log(ev);
            },2000));
        }
    </script>
</body>
</html>

高频事件性能优化-函数防抖
比如说大家非常熟悉的搜索引擎的联想查询功能。它是在用户进行键入的同时进行的数据请求。
但是键盘事件触发的频率是按照字母来计算的,不是按照汉字或者单词,如果是每键入一个字母都触发一次数据请求,就非常的低效。在这种情况下,我们就有必要降低这种操作的频率,保证一定时间内,核心代码只执行一次。这样在核心代码块比较沉重的时候,就会大大提升我们的性能了。

核心思路:是指触发时间后再n秒内只能执行一次,如果再n秒内又触发了该事件,则重新计算时间

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <input type="text" id="search">
    <script>
        window.onload=function(){
            //防抖
            function fn(callback,wait){
                let timer=null; //  记录计时器的id
                return function(){
                    let args=arguments;
                    if(timer) clearTimeout(timer);
                    timer=setTimeout(function(){
                        callback.apply(this,args);
                    }.bind(this),wait);
                }
            }

            let search=document.getElementById('search');
            search.addEventListener('input',fn(function(){
                let script=document.createElement('script');
                script.src="https://www.baidu.com/sugrec?pre=1&p=3&ie=utf-8&json=1&prod=pc&from=pc_web&sugsid=32095,1422,31326,21125,31069,31253,32045,30823,26350&wd="+this.value+"&req=2&csor=3&pwd=12&cb=callBack&_=1592456567512";
                document.body.appendChild(script);
                document.body.removeChild(script);
            },2000));
        }
        function callBack(data){
            console.log(data);
        }
    </script>
</body>
</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值