js闭包

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>闭包</title>
</head>
<body>
<ul>
    <li>li1</li>
    <li>li2</li>
    <li>li3</li>
    <li>li4</li>
    <li>li5</li>
</ul>
<script type="text/javascript">
    //前提知识: 函数内部可以使用函数外部的变量;函数外面不能使用函数内部的变量。
    // function f1(){
    //     var num = 100;
    //     function f2(){
    //         console.log(num);
    //     }
    //     return f2;
    // }
    // var res = f1(); // res = f2;  将f2函数 返回到 f1外面
    // // console.log(res);
    // res(); // f1函数外面 调用f2函数,使用到了f1函数内部的变量,这种方式就是写了一个“闭包”
    //闭包 其实就是 一个内部函数,或者说 闭包是一个内部函数以及函数所处的作用域环境
    //闭包典型特征:两个函数嵌套,内部函数被外部函数返回了.
    
    //闭包可以使用匿名函数的写法(闭包和匿名函数的关系)
    // function f1(){
    //     var num = 200;
    //     return function(){
    //         console.log(num);
    //     };
    // }
    // var res = f1();
    // res();

    // //更彻底的匿名函数用法
    // var res = (function(){
    //     var num = 300;
    //     return function(){
    //         console.log(num);
    //     };
    // })();
    // // res 就是内部的函数
    // res();


    //特殊写法:函数本身所处的作用域
    // 函数本身所处的作用域,取决于函数定义的位置,和函数调用的位置无关
    //例子1
/*    var num = 100;
    var f = function(){
        console.log(num);
    };

    function f1(){
        var num = 200;
        return f;
    }
    var res = f1(); // res 就是 f函数
    res();

*/
//例子2
    // var num = 100;
    // var f = function(){
    //     console.log(num);
    // };

    // function f1(){
    //     var num = 200;
    //     f();
    // }
    // f1();

    //循环绑定事件; 事件中i丢失问题
    //原因:事件函数,是在循环结束之后才出发,循环结束,全局变量i已经是5
    //事件函数中使用全局变量i,始终是5
    // var lis = document.querySelectorAll('li');
    // for(var i=0; i<lis.length; i++){
    //     lis[i].onclick = function(){
    //         //输出 我是第 几 个li标签
    //         console.log('我是第 ' + i + ' 个li标签');
    //     }
    // }

    //解决办法 : 使用闭包方法
    var lis = document.querySelectorAll('li');
    for(var i=0; i<lis.length; i++){
        //套一层匿名函数自调用,形成了一个闭包环境
        //主要作用是形成一个局部作用域
        (function(m){
            lis[m].onclick = function(){
                //输出 我是第 几 个li标签
                console.log('我是第 ' + m + ' 个li标签');
            }
        })(i);
        
        //循环5次;每次都产生一个局部作用域,局部变量m的值都不一样,互相不影响
        //第一个局部作用域  m = 0
        //第二个局部作用域  m = 1
        //。。。。
        //局部变量和全局变量 互相不影响
        //不同作用域的局部变量 互相不影响
    }
</script>
</body>
</html>

 

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>闭包-常驻内存</title>
</head>
<body>
<script type="text/javascript">
    //1.闭包能够使 函数外部使用函数内部的变量(对外部函数来说)
    //2.闭包能够是 函数内部的变量,常驻内存(数据始终保存在内存中,不会被销毁)
    // function fn(){
    //     var num = 100;
    //     console.log(num);
    //     num++;
    // }
    // fn();//100
    // fn();//100
    //闭包缺点:由于内部数据不会被自动销毁,占用内存。所以一般不要使用太多闭包
    function f1(){
        var num = 100;
        return function(){
            console.log(num);
            num++;
        };
    }
    var res = f1(); // res就是返回的那个函数
    res(); // 100  num = 101
    res(); // 101  num = 102
    res(); // 102  num = 103
</script>
</body>
</html>

 

posted @ 2021-02-23 20:51  华北业余选手  阅读(13)  评论(0)    收藏  举报