Javascript漂流记(上)__作用域链、闭包、立即执行函数

版权声明:本文为博主原创,转载请附上博文链接。 https://blog.csdn.net/AquamanTrident/article/details/90549933

一、作用域[[scope]]:
    存储了执行期上下文的集合(作用域链)
    参照下图代码:
    a函数被定义时:a.[[scope]]--> 0:GO{}

    a函数执行时:a.[[scope]]--> 0:aAO{}
                                                 1:GO{}

    a函数执行时,b函数被定义:b.[[scope]]-->0:aAO{}
                                                                        1:GO{}

    b函数毫不客气地带上了老爹a函数的劳动成果。


    b函数执行时:b.[[scope]]-->0:bAO{}
                                                1:aAO{}
                                                2:GO{}

    在哪个函数里查找变量,就从哪个函数的作用域链的顶端依次向下查找
    b函数执行结束,摧毁自己的执行期上下文,回归到被定义时的状态,等待下一次执行
    a函数执行结束,摧毁自己的执行期上下文(同时摧毁了整个b函数),回归到被定义时的状态,等待下一次执行

二、闭包:还是举栗说明

                  当a函数将其内部的b函数return,并赋给外部变量demo时,
                  此时的b函数保存了a函数执行时的作用域链,不会被释放。形成闭包。


 

       如此一来,若过多的作用域链不被释放,占用大量内存,造成内存泄露。

       闭包的应用:

               1、用做缓存(存储结构)          

            function eater(){
                var food = '';
                var obj = {
                    eat: function() {
                        console.log('I am eating ' + food);
                        food = '';
                    },
                    push: function(myFood){
                        food = myFood;
                    }
                }
                return obj;
            }
            var eater1 = eater();
            eater1.push('banana');
            eater1.eat();

               2、实现公有变量,函数累加器

            function add(){
                var count = 0;
                function demo(){
                    count++;
                    console.log(count);
                }
                return demo;
            }
            var counter = add();
            counter();//1
            counter();//2
            counter();//3

               3 、实现属性私有化(第二块代码为圣杯模式,后续继承会涉及),别人访问不到,自己可以操作。

            function Person(name,club){
                var prepareClub = 'Laker';

                this.name = name;
                this.club = club;
                this.changeClub = function(){
                    this.club = prepareClub;
                }
                this.changePrepareClub = function(target){
                    prepareClub = target;
                }
                this.sayPrepareClub = function(){
                    console.log(prepareClub);
                }
            }   
            var person = new Person('Jame','Heat');

                    下图代码为圣杯模式,后续继承模式会详细说明。

            var inherit = (function(){
                var F = function(){};
                return function(Target,Origin){
                    F.prototype = Orgin.prototype;
                    Target.prototype = new F();
                    Target.prototype.constructor = Target;
                    Target.prototype.uber = Origin.prototype;
                }
            }());

               4、模块化开发,防止污染全局变量

            var name = 'bcd';
            var initJack = (function(){
                var name = 'abc';
                function callName(){
                    console.log(name);
                }
                return function(){
                    callName();
                }
            }());
            initJack();

三、立即执行函数:有些函数只需要执行一次,初始化功能,执行完立即释放。

            var num = (function(a,b){
                return a + b;
	        }(3,5));
            console.log(num);//8

        立即执行函数拓展:
               只有表达式才能被执行符号执行!!!如下列代码,+、-将函数test转换为表达式
               能被执行符号执行的函数表达式,自动放弃函数名称。

            +function test(){
                console.log('a');
            }();
            
            -function test(){
                console.log('b');
            }();

               经典鄙视题 :以下代码如何执行?

            function demo(a,b,c,d){
                return a + b + c + d;
            }(1,2,3,4)

四、闭包的防范:如下两段代码,感受一下。

            function test(){
                var arr = [];
                for(var i = 0; i < 10; i++){
                    arr[i] = function(){
                        console.log(i);//打印10个10
                    }
                }
                return arr;
            }
            var myArr = test();
            for(var j = 0; j < 10; j++){
                myArr[j]();
            }
            function test(){
                var arr = [];
                for(var i = 0; i < 10; i++){
                    (function(j){
                        arr[j] = function(){
                            console.log(j);//0123456789
                        }
                    }(i));
                }
                return arr;
            }
            var myArr = test();
            for(var j = 0; j < 10; j++){
                myArr[j]();
            }

以上内容属二哥原创,整理自 "渡一教育Javascript课程" ,一个值得推荐的"渡一教育"。

猜你喜欢

转载自blog.csdn.net/AquamanTrident/article/details/90549933
今日推荐