前端基础学习

闭包

2020-04-27  本文已影响0人  小雪洁
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>闭包</title>
    </head>
    <body>
    </body>
    <script>
//子函数可以访问到父级函数的作用域,这种现象称为闭包
    let arr=[1,23,4,6,17,3,10,2,5,7,9];
    //选出5到9之间的数
    let a=arr.filter(function(v){
        return v>=5&&v<=9;
    });
    console.log(a);
    //选出3到7之间的数
    let b=arr.filter(function(v){
        return v>=3&&v<=7;
    });
    console.log(b);
//考虑函数复用,子函数可以return父级作用域的某些数据,这是闭包的一个很大的特性
    function between(a,b){
        return function(v){
            return v>=a&&v<=b;
        }
    }
    let c=arr.filter(between(2,8));
    console.log(c);
    
    </script>
</html>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>移动动画的闭包使用</title>
    </head>
    <style>
        button{
            position: absolute;
            left:0;
        }
    </style>
    <body>
        <button>hao</button>
        <button>yangdingchuan</button>
    </body>
    <script>
        let btns=document.querySelectorAll('button');
        [...btns].forEach(function(item){
            let left=1;
            let sitid=false;
            item.addEventListener('click',function(e){
//问题一、如果left在这里定义,点击第二次时会出现抖动,因为每次点击都会触发使left重新定义
        //解决办法是把left放到点击事件外部定义
                //let left=1;
//问题二、left放到点击事件外部定义,解决了抖动但是会在每次点击都会加速按钮的移动
//因为每次点击都会重新创建一个定时器,这样点击10次就是创建10个定时器,不是每100ms的速度移动了
//而成了每10ms自增的速度了
            /* setInterval(function(){
                        item.style.left=`${left++}px`;
                },100); */
            
            //解决办法:存一个标志,如果定时器已经建立了就不在重复创建了
            if(sitid==false){
                sitid=true;
                setInterval(function(){
                            item.style.left=`${left++}px`;
                    },100);
            }
            });
        });
    </script>
</html>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>利用闭包根据字段排序商品</title>
    </head>
    <body>
    </body>
    <script>
        let goods=[
            {
                name:'banana',
                price:10,
                click:30
            },
            {
                name:'apple',
                price:5,
                click:40
            },
            {
                name:'grape',
                price:15,
                click:32
            }
        ];
        //按价格升序
        let g0=goods.sort(function(a,b){
            return a.price>b.price?1:-1;
        });
        console.log(g0);
        //按点击次数降序
        let g1=goods.sort(function(a,b){
            return a.click<b.click?1:-1;
        });
        console.log(g1);
        //考虑代码复用
        function order(field){
            return function(a,b){
                //升序
                return a[field]>b[field]?1:-1;
                //降序
                //return a[field]<b[field]?1:-1;
            }
        }
        let g2=goods.sort(order("price"));
        console.log(g2);
    </script>
</html>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>闭包的内存泄露解决办法</title>
    </head>
    <body>
        <div name='haoxuejie'>郝雪洁</div>
        <div name='yangdingchuan'>杨定川</div>
    </body>
    <script>
        let divs=document.querySelectorAll("div");
        /* [...divs].forEach(function(item){
            item.addEventListener('click',function(){
                console.log(item.getAttribute('name'));
                console.log(item);
            });
            //每次都会在内存中存大量的dom节点,
            //如果dom元素内容比较多,会引起内存泄露
        }); */
        //改进办法
        [...divs].forEach(function(item){
            let name=item.getAttribute('name');
            item.addEventListener('click',function(){
                console.log(name);
                console.log(item);//null
            });
            item=null;//及时清理内存,可以使程序运行更快一些
        });
    </script>
</html>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>this在闭包中的历史遗留问题</title>
    </head>
    <body>
    </body>
    <script>
        let hxj={
            user:"haoxuejie",
            get:function(){
                return this.user;
            },
            get0:function(){
                return function(){
                    return this.user;
                }
            },
            get1:function(){
                return ()=>{
                    return this.user;
                }
            }
        };
        let h=hxj.get();
        console.log(h);//haoxuejie
        let x=hxj.get0();
        console.log(x);//是一个函数
        console.log(x());//undefined,因为此时x是全局对象,它的this指向的是window,window里面没有user这个变量
//使用箭头函数解决上述问题,get1()内部定义的返回函数是使用箭头函数定义的
        let j=hxj.get1();
        console.log(j);//输出一个箭头函数
        console.log(j());//haoxuejie
            
    </script>
</html>
上一篇下一篇

猜你喜欢

热点阅读