首页 > 为什么这里面的B执行完了会被垃圾回收了。。什么时候才不会被回收

为什么这里面的B执行完了会被垃圾回收了。。什么时候才不会被回收

<script type="text/javascript">     
         function start(){
             var b=0;
             function cd(){
                 ++b;
                 console.log(b); 
             }
             cd();         
         }
        start();
        start();
    </script>

如题,为什么这个B都会弹出1,不应该是里面的cd函数引用这个B,不会被清除么。


function start()
{
    var b=0;
    function cd(){
         ++b;
        console.log(b); 
    }
    cd();         
}
start();
start();

GC只会清理那些你绝对访问不到的变量。在我们写JS看来GC仅仅js引擎对js代码的优化,即使我们认为任何分配的变量都不会被回收也没有关系。

现在我们看看如何便会无法访问到一个变量。
JS(ES5.1)是函数作用域,也就说JS的函数执行一次才会生成一个作用域,而函数作用域的父作用域主要看函数定义所在的位置。如上代码,所有代码执行前只有一个作用域--全局作用域。其中定义了一个变量/函数(除了JS预定义的全局变量)--start
当第一次执行start,这个时候会生成一级作用域,假设我们叫他start1,其中定义了两个变量b(然后被赋值为0),cd。然后执行cd()函数,首先在本作用域(start1)中查找cd,当然是有喽。执行cd函数的时候也生成一级作用域,由于cd 是在start1 中定义的,因此,新生成的作用域的父作用域是start1。当函数中使用了b的时候,在本作用域没有,于是到start1中去找,就找到了start1中的b。那么引用的就是这个变量。

当再一次执行 start,这个时候也会生成一级作用域,假设我们叫他start2,其中定义了两个变量b(然后被赋值为0),cd(与start1中的那两个变量没关系,只是重名)。然后执行cd()函数,首先在本作用域(start2)中查找cd,当然是有。执行cd函数的时候也生成一级作用域,由于cd 是在start2 中定义的,因此,新生成的作用域的父作用域是start2。当函数中使用了b的时候,在本作用域没有,于是到start2中去找,就找到了start2中的b。那么引用的就是这个变量。

这样函数执行完之后,我们就无法访问到 start1中的 b和cd ,也无法访问到start2中的b和cd了。因为:第一,代码不再他们的作用域中了,第二,他们也无法成为其他作用域的父(祖先)作用域。

如下代码,自己用上面的方式分析执行结果。

function start()
{
    var b=0;
    function cd(){
         ++b;
        console.log(b); 
    }
    return cd;         
}
cd1 = start();
cd1();
cd1();
cd2 = start();
cd2();
cd2();

这种现象叫做闭包,详见我的另一个回答:https://.com/q/1010000004736...


chrome里面,这个确实是闭包

YDKJS里面也讲过这个东西

但是严格来讲,闭包应该是从一个函数A中返回了函数B,并且B有对A函数中变量的引用


你每次都申明了次b=0


闭包里面的函数不会立即清掉的 推荐你看个东西 http://www.cnblogs.com/wangfupeng1988/p/...


b是在start内部声明并赋值的,作用域在start内部,在下次调用时重新声明并重新赋值为0了。


你这就是闭包函数,每次引用都会重置内部变量,因此在你引用的时候都是更新内部变量,所以每次都会重新使得b=1;所以怎么样都会输出1,return方法也是一样的道理


b和cd都是定义在start里的
每次start执行,都定义了一个新的b和新的cd

感觉提主要的效果应该是这样

function start(){
     var b=0;
     function cd(){
         ++b;
         console.log(b); 
     }
     return cd;        
 }
 
 var cd = start();
 cd();
 cd();
 
【热门文章】
【热门文章】