在想弄清楚这个之前,你需要了解栈内存、堆内存和预处理。占用内存且不会被销毁的闭包示例1:varnum=12;functionfn(){varnum=100;返回函数(){console.log(num);}}varf=fn();f();Example1插图中未占用的堆内存将被销毁。因此,如图中椭圆关键点说明,堆内存xxxfff111归还给全局变量f,该全局变量只有在窗口关闭时才可用。因此,堆内存xxxfff111会一直被占用,不会被销毁,定义它的局部作用域A也不会被销毁。示例2varoDiv=document.getElementById("div1");~function(){oDiv.onclick=function(){}}();这段代码的特点是:私有作用域绑定了一个方法到DOM元素的事件上。例二示意图:图中椭圆关键点提到,label对象的属性会有一个onclick属性,不赋值时它的值为null。然后,当自执行函数执行时,创建的scope占用的堆内存xxxfff111也会被全局堆内存xxxfff000占用(这里需要注意的是堆内存占用堆内存),所以堆内存xxxfff111和堆栈内存A都不会被销毁。不占用内存立即销毁的实例只需要对示例1稍作修改即可。示例3:functionfn(){varnum=100;返回函数(){console.log(num);}}fn();//这里主要修改例3中的图示,因为在函数fn中,返回了xxxfff111,所以栈内存A的预解释不会处理xxxfff111,只会在fn函数执行时产生,而栈内存A函数fn的每次执行都会被销毁。暂时占用内存,延迟销毁的闭包实例稍微修改一下Example3,就会变成延迟销毁的闭包实例。示例4:函数fn(){varnum=100;返回函数(){}}fn()();//这到底是怎么回事?事实上,fn执行一次后,返回的子函数也被执行一次,所以子函数执行时,栈内存fn()不能被销毁,而是因为子函数执行完后没有被占用,最后fn()还是会被销毁。例4说明:图中椭圆关键点提到,fn()()表示执行完fn()后,再次执行返回值函数。因此,子函数执行时,堆内存xxxfff111被占用,相应的栈内存A也会被保留。可堆内存xxxfff111中存放的子函数在执行完成后仍然会被销毁,然后堆内存xxxfff111会作为未被占用的堆内存被销毁,最后栈内存A也会被销毁。所以栈内存在执行后会被保留一段时间,这段时间等于其子函数的执行时间。参考资料:JavaScript高级程序设计(第三版)。我在github上https://github.com/zhuanyongx...
