当前位置: 首页 > Web前端 > JavaScript

关闭?什么是闭包?--JavaScript前端

时间:2023-03-26 20:45:20 JavaScript

闭包后台由于js中只有两个作用域,全局作用域和函数作用域,在开发场景下,将变量暴露到全局作用域是非常危险的,尤其是在团队协同开发的时候,变量的值会被无意中篡改,调试分析难度极大。在这种情况下,闭包将变量封装在局部函数范围内是一种非常合适的做法,以避免其他代码的干扰。闭包的使用下面是一个最简单直接的闭包例子//motherbodyfunctionmother(){//口袋里的总金额letmoney=100//消费行为returnfunction(pay){//returntheremainingTheremainingmoneyreturnmoney-pay}}//给儿子消费letpayForSon=mother()//打印最后剩余的钱console.log(payForSon(5))为了便于理解,我们比较外部函数传给母体,并在里面保存总金额变量和消费行为,通过为儿子创建消费行为对象,然后执行该行为消费5元,返还剩余95元元。这是为了将变量money保存在mother本身,避免暴露在外部全局环境范围内。只有通过mother()创建消费行为才能影响变量money。由此,我们可以总结出使用闭包的三个步骤。用外部函数包装变量和函数;外部函数返回内部函数;外部使用变量来保存外部函数返回的内部函数。外层函数返回的内层函数的目的是形成一个专用变量。在专用范围内操作。在上面的闭包代码示例中,存在一个缺陷场景,就是money变量在后面不需要的时候没有释放,导致内存泄漏。原因是函数payForSon的范围链引用了money对象。解决办法是通过设置payForSon=null来释放方法作用域,然后释放对money的引用,最后释放money变量。闭包的扩展函数柯里化在开发场景中,有时需要通过闭包来实现函数的柯里化调用。调用示例如下:alert(add(1)(2)(3))这种连续的参数调用函数称为函数柯里化。通过闭包的实现方法如下functionadd(a){//保存第一个参数letsum=afunctiontmp(b){//从第二个函数增加sum=sum+b//返回tmp,让后续继续传递参数并执行returntmp}tmp.toString=function(){returnsum}//返回加法函数returntmp}alert(add(1)(2)(3))下面一步步分析步骤,add(1)执行时,将第一个参数保存到sum变量中,返回tmp函数add(1)(2)执行等于tmp(2),将2的值加到变量sum中,返回tmp函数本身add(1))(2)(3)的执行等同于上面的步骤对ratio变量sum进行加法运算,返回tmp函数本身。执行alert(add(1)(2)(3))时,alert需要将值转换成字符串显示,最后tmp函数执行tmp.toString,返回sum的值。MatrixClickApplication这个例子的demo代码在我的github上,需求可以自己看:在一个4*4的矩阵盒子里,点击每个按钮记录点击次数,互不干扰。思路:在按钮事件中使用闭包来创建独立的存储变量空间。注:以下方案1~3为渐进式优化方案,需要按照方案标签的顺序逐层理解,更有利于理解最终的优化方案方案1

..letcontainer=document.getElementById('container')for(letr=0;r