<script type="text/javascript">
function start(){
var b=0;
function cd(){
++b;
console.log(b);
}
cd();
}
start();
start();
</script>
如题,为什么这个B都会弹出1,不应该是里面的cd函数引用这个B,不会被清除么。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
b和cd都是定义在start里的
每次start执行,都定义了一个新的b和新的cd
感觉提主要的效果应该是这样
b是在start内部声明并赋值的,作用域在start内部,在下次调用时重新声明并重新赋值为0了。
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了。因为:第一,代码不再他们的作用域中了,第二,他们也无法成为其他作用域的父(祖先)作用域。如下代码,自己用上面的方式分析执行结果。
这种现象叫做闭包,详见我的另一个回答:https://segmentfault.com/q/1010000004736...
你这就是闭包函数,每次引用都会重置内部变量,因此在你引用的时候都是更新内部变量,所以每次都会重新使得b=1;所以怎么样都会输出1,return方法也是一样的道理
你每次都申明了次b=0
闭包里面的函数不会立即清掉的 推荐你看个东西 http://www.cnblogs.com/wangfupeng1988/p/...
chrome里面,这个确实是闭包
YDKJS里面也讲过这个东西
但是严格来讲,闭包应该是从一个函数A中返回了函数B,并且B有对A函数中变量的引用