Javascript漂流记(上)

    xiaoxiao2023-11-09  152

    一、作用域[[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课程" ,一个值得推荐的"渡一教育"。

    最新回复(0)