作用域、立即执行函数、闭包

一、作用域

            function a() {
                function b() {
                    function c() {
                         //something
                    }
                    c();
                }
                b();
            }
            a();

            a defined a.[[scope]] -- > 0 : GO

            a doing   a.[[scope]] -- > 0 : aAO
                                       1 : GO

            b defined b.[[scope]] -- > 0 : aAO
                                       1 : GO

            b doing   b.[[scope]] -- > 0 : bAO
                                       1 : aAO
                                       2 : GO

            c defined c.[[scope]] -- > 0 : bAO
                                       1 : aAO
                                       2 : GO

            c doing   c.[[scope]] -- > 0 : cAO
                                       1 : bAO
                                       2 : aAO
                                       3 : GO

二、立即执行函数

        1.立即执行函数,执行完后立即销毁(释放)即针对初始化功能的函数
        2.对于函数,只有表达式才能被执行,外面有一层括号使之成为表达式

            var num = (function (a,b,c) {
                var d = a + b + c;
                return d;   
            }(1,2,3));   

三、闭包

1.函数累加器(可以不依赖于全局变量)
                function add() {
                    var count = 0;
                    function demo() {
                        count ++;
                        console.log(count);
                    }
                    return demo;
                }
                var counter = add();
                counter();
                counter();
2.可以做缓存(存储结构)
             1.  用对象返回两个函数
                function test() {
                    var food = "apple";
                    var obj = {
                        eat : function () {
                            if (food != "") {
                                console.log("I am eating " + food);
                                food = "";
                            }else{
                                console.log("There is nothing!");
                            }
                        },
                        pushFood : function (x) {
                            food = x;
                        }
                    }
                    return obj;
                }
                //用对象的形式返回出来,简化返回两个函数
                var person = test();

                person.eat();
                person.eat();
                person.pushFood('banana');
                person.eat();


            2  . 用数组返回两个函数
                function test() {
                    var num = 100;
                    function a() {
                        num ++;
                        console.log(num);
                    }           
                    function b() {
                        num --;
                        console.log(num);
                    }
                    return [a,b];
                }       
                var myArr = test();
                myArr[0]();
                myArr[1]();
3.可以实现封装,属性私有化
            function Deng(name, wife) {
                var prepareWife = 'xiaozhang';
                this.name = name;
                this.wife = wife;
                this.divorce = function () {
                    this.wife = prepareWife;
                }
                this.sayPrepareWife = function () {
                    console.log(prepareWife);
                }
            }

            var deng = new Deng('deng', 'xiaoliu');

            console.log(deng.prepareWife);  // undefined
            console.log(deng.sayPrepareWife()); //xiaozhang  闭包
4.模块化开发,防止污染全局变量
            变量可以不互相污染
            var name = "xyz";

            var init = (function () {
                var name = "abc";
                function callName() {
                    console.log(name);
                }
                return function () {
                    callName();
                }
            }());

            var initDeng = (function () {
                var name = "def";
                function callName() {
                    console.log(name);
                }
                return function () {
                    callName(); 
                }
            }());

            init();
            initDeng();

闭包产生的问题实例 (1)

              会打印出十个10
                function test() {
                    var arr = [];
                    for(var i = 0; i < 10; i ++){
                        arr[i] = function () {
                            document.write(i);
                        }
                    }
                    return arr;
                }

                var myArr = test();
                for(var j = 0; j < 10; j ++){
                    myArr[j]();
                }

解决方法(唯一)

              会打印出 0 - 9
                function test() {
                    var arr = [];
                    for(var i = 0; i < 10; i ++){
                        (function (x) {
                            arr[x] = function () {
                                document.write(x + " ");
                            }
                        }(i));
                    }
                    return arr;
                }

                var myArr = test();
                for(var j = 0; j < 10; j ++){
                    myArr[j]();
                }

闭包产生的问题实例及其解决 (2)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style type="text/css">
        *{
            margin: 0;
            padding: 0;
        }
        ul{
            list-style: none;
        }
        li:nth-of-type(2n){
            background-color: red;
        }
        li:nth-of-type(2n + 1){
            background-color: green;
        }
    </style>
</head>
<body>
    <ul>
        <li>a</li>
        <li>a</li>
        <li>a</li>
        <li>a</li>
    </ul>
    <script type="text/javascript">
        1.闭包产生的索引皆为4
        function test() {
            var liCollection = document.getElementsByTagName('li');

            for(var i = 0; i < liCollection.length; i ++){
                liCollection[i].onclick = function () {
                    console.log(i);
                }
            }
        }

        test();

        2.解决后索引为0 1 2 3
        function test() {
            var liCollection = document.getElementsByTagName('li');

            for(var i = 0; i < liCollection.length; i ++){
                (function (x) {
                    liCollection[x].onclick = function () {
                        console.log(x);
                    }
                }(i))
            }
        }
        
        test();
    </script>
</body>
</html>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容