关于闭包的那点事

本文详细解析了JavaScript中闭包的概念及其工作原理,并通过多个示例展示了如何利用闭包实现变量保护和状态维护等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

官方解释:
当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。


function a(){
    function b(){
    }
}   

个人理解:当函数b可以记住并访问所在的a函数的作用域时,就产生了闭包,即使函数b是在a函数的作用域之外执行。
举个例子:
1、

<script>         
    var i = 0;
    document.onclick = add;
    function add(){
       i++;
       document.title =i;
    };
</script>

第一个例子都能看懂,是个简简单单的实现 i 累加。
2、


<script>         
    document.onclick = add;
    function add(){
       var i = 0;
       i++;
       document.title =i; 
    };
</script>

第二个例子:将i定义在函数内部,会发现 i 这时候无法实现累加,一直显示是1。这是为什么?


原因:
1、第一个例子的 i 定义在函数外面,它在一个叫做”全局作用域”的区域里面。”全局作用域”只会在浏览器窗口关闭或页面刷新的时候进行关闭。(我们跟第二个例子对比下就知道全局作用域)。

2、第二个例子的 i 定义在函数里面,它在一个叫做”函数作用域”的区域里面。”函数作用域”会在函数被调用的时候创建,而在函数运行结束的时候关闭(并且里面创建的变量跟函数也会被删掉–垃圾回收机制)。

3、通过上面的说法:我们就知道了,第一个例子能实现累加,是因为 i 一直储存在全局作用域,没有被删掉。第二个例子,我们调用了函数,然后创建了函数作用域->定义了 i->函数运行结束后->函数作用域关闭了,i 也被删除了。然后我们再点击, 又重新创建了函数作用域,重新定义 i 。(我们点击是在不停重新创建 i)


问题:有没有办法让“函数作用域”不关掉呢? ————- 那就是”闭包”了。

3、闭包

<script>         
    document.onclick =add1();
    function add1(){    
        var i = 0;
        function add2() {
        i++;
        document.title =i;
       }
       return add2;        //运行add1()的获得的值是add2
    }
</script>

这次还是将 i 定义到函数里面,但我们会发现,i 实现了累加。 这说明我们已经让函数作用域不关闭了,这就是简单的闭包。


原因:
我们来分析为什么函数作用域没有被关闭:

①我们在函数内部定义了 i

②定义了函数 add2(),并且在add2()引用了 i

③最后return add2。

④(要注意的是:这里document.οnclick=add1(); 直接执行了add1函数,获取到了add1() 的值,而值是我们return的add2函数)。其实相当于 documen.onclick = add2 //为了方便理解,我们假设它存在 ;

⑤ 这时就会发现,我们在全局环境中使用在add1函数里面定义的add2函数。

⑥ 因为documen.onclick = add2;的存在,既是作用域链的存在。只要浏览器不被关闭,全局作用域对add2的依赖就会一直存在,而add2的执行依赖add1()里面定义的 i,使得add1()也不会被关闭,i 也不会被重新定义,累加的值也被成功的保存下来。


4、闭包

<script>         
    document.onclick =(function(){ //匿名函数自执行
        var i = 0; 
        return function() {       //返回另一个匿名函数
            i++; 
            document.title =i; 
        } 
    })();
</script>

这里涉及到“匿名函数自执行”。(function(){})(); 一般执行函数是在函数名后面加括号,这里(function(){})相当于一个表达式,我们在它后面加(); 。就相当于执行了这个函数。 同样的,我们 return function(){}; 。 也是把这个函数返回出去了,只不过返回出去一个匿名函数。

5、闭包作用

<script>    
    var i = 10 ;     
    document.onclick =(function(){ 
        var i = 0; 
        return function() {       
            i++; 
            document.title =i; 
        } 
    })();
    console.log(i);
</script>

有蛮多初学者说,都听别人闭包好用,可是不知道他的实际应用。像第五个例子,我在全局也定义了一个 i ,也对它进行了控制台输出,发现我们闭包里的函数并不会对全局造成影响,却实现了全局的效果。对于比较大型的合作项目,很多人分工合作,如果每个人都在全局定义变量 ,如果定义了同样名字的变量,对这两个人的程序都会造成一些影响。 这就是闭包的效果。

还有点需要注意的是:闭包的存在会使得他不会被垃圾回收机制回收,他会比其他函数占更多的内存,过渡使用闭包可能会导致内存占用过多。可能会导致浏览器崩溃的问题。解决方法就是已经达到我们的目的的时候,解除对匿名函数的引用,没有了引用变成了普通函数,被垃圾回收机制回收。

内容概要:该研究通过在黑龙江省某示范村进行24小时实地测试,比较了燃煤炉具与自动/手动进料生物质炉具的污染物排放特征。结果显示,生物质炉具相比燃煤炉具显著降低了PM2.5、CO和SO2的排放(自动进料分别降低41.2%、54.3%、40.0%;手动进料降低35.3%、22.1%、20.0%),但NOx排放未降低甚至有所增加。研究还发现,经济性和便利性是影响生物质炉具推广的重要因素。该研究不仅提供了实际排放数据支持,还通过Python代码详细复现了排放特征比较、减排效果计算和结果可视化,进一步探讨了燃料性质、动态排放特征、碳平衡计算以及政策建议。 适合人群:从环境科学研究的学者、政府环保部门工作人员、能源政策制定者、关注农村能源转型的社会人士。 使用场景及目标:①评估生物质炉具在农村地区的推广潜力;②为政策制定者提供科学依据,优化补贴政策;③帮助研究人员深入了解生物质炉具的排放特征和技术改进方向;④为企业研发更高效的生物质炉具提供参考。 其他说明:该研究通过大量数据分析和模拟,揭示了生物质炉具在实际应用中的优和挑战,特别是NOx排放增加的问题。研究还提出了多项具体的技术改进方向和政策建议,如优化进料方式、提高热效率、建设本地颗粒厂等,为生物质炉具的广泛推广提供了可行路径。此外,研究还开发了一个智能政策建议生成系统,可以根据不同地区的特征定制化生成政策建议,为农村能源转型提供了有力支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值