当前位置: 首页 > 后端技术 > Node.js

为什么哈士奇系列的JavaScriptClosure

时间:2023-04-03 11:11:40 Node.js

标题叫HandledHusky?因为闭关一直在我的脑海里挥之不去,到底有多久了?(打断手指和脚趾ing。。。)大概是笔者从事前端工作的第一个月吧。。。还记得当时问过公司的大神,不过那只是因为我的那个时候脑子不好So,反正我就是没看懂,哎!不过最近项目没那么忙,回过头来研究一下前端一直没变的话题之一:闭包。诚然闭包对于JavaScript初学者来说有点难理解,但相信即使是初学者看了这篇博文后也会对闭包有更深的理解(“王婆卖瓜,卖瓜自夸”),哈哈...废话少说,开始吧。题目介绍在开始介绍闭包之前,笔者先记下。我们先思考这个问题:如何从函数A外部访问函数A中的变量?不了解闭包的朋友可能会觉得这是土拨鼠系列一样的傻问题,就一个字:废话(手动搞笑)。即便如此,作者还是厚着脸皮贴出了上一篇博客的地址,因为这篇博客对解决这个问题有很大的帮助。下面我们一起来思考一下如何回答上面的问题:根据之前博客的描述,如果要访问一个变量,就必须在该变量的作用域内进行访问;其次,在函数中访问变量,只能在函数Something(hand)love(feet)中进行,例如:functionclosure(){letname='Husky';让年龄=2;//访问变量}既然已经在函数中访问了,那怎么实现在函数外访问呢?答案肯定是肯定的,只要你做点什么(手)爱(脚),但不要急着想做什么,让我们想象一个很(哀)正常(心)有趣(病)疯)的场景:隔壁老王是房东,今天有个美女要租他的房子。美女真是个(胸)体(大)挺(臀)气(翘),所以老王想借此机会看(偷)(窥)。但是每天晚上,房间的门窗都关的严严实实的,所以老王就偷偷在里面装了个摄像头,然后肆无忌惮的……(手动滑稽)场景描述到这里就结束了,但是小伙伴们不要让你的想象力天马行空。毕竟作者正直,哎!改变上面的代码来表达上面的情况:functionRoom(){letbeauty='likeaflower';//camera}那么摄像头就可以捕捉(参观)捕捉(询问)房间(功能)房间(编号)内(体)像(量)的影子(变化),同时,拍摄的场景可以传回老王的屏幕。因此,可以想象,我们在函数中放置一个对象,然后访问对象中的变量,返回该对象。我们收到返回的对象后,就可以访问外面的变量了!宾果……就是这样。俗话说,JavaScript世界中的一切都是对象(函数也是对象)。所以我们可以这样补充上面的代码:functionRoom(){letbeauty='likeaflower';//相机letcamera=function(){returnbeauty;}}这样我们就可以得到一个函数,相当于摄像头的信号线,通过这个可以得到图像:functionRoom(){letbeauty='likeaflower';//相机letcamera=function(){returnbeauty;}returncamera`请输入代码`;}letcamera=Room();letbeauty=camera();console.log(`老王看到${beauty}`);看运行结果:然后我们帮老王如愿看到花,继续那不可描述的夜夜事。(看我正脸。。。)说到这里,关于闭包的事情就浮出水面了。Closure闭包,目前还没有统一的定义。作者的理解是,闭包是由函数体中的变量和访问该变量的函数组成的系统。对应上面的代码是:beauty和cameraclosures只是这类系统的名称,它们的英文名称是Closure;闭包实际上并不意味着关闭,相反,它们也只是通过一定的约束(函数)将内部变量暴露给外部。例如:functionclosure(){letfronted=['js','css'];返回函数(){返回前面;}}letfronted=closure()();<----运行两次,运行闭包和返回的匿名函数console.log(fronted);fronted.push('html');控制台日志(前面);我们在函数中声明一个数组并初始化它,最后通过匿名函数(推荐使用匿名函数)返回。这样我们就可以在函数外获取内部数组,进行一些操作。以上操作结果如下:Chrome浏览器是如何识别闭包的?不同的浏览器对闭包有不同的理解。接下来,笔者使用世界上最好的浏览器Chrome来演示它是如何识别闭包的。还是用上面的代码:首先,我们需要打两个断点,运行第一步,请注意第二步运行截图中的红框,同样请观察截图中的红框。它与上一步不同。是的,还有一个额外的“Closure”对象,它指向(闭包)函数。解释到此结束Chrome已将此识别为闭包。展开这个对象:果然,世界上最好的浏览器,向我们展示了闭包中访问的变量。神器,有没有...闭包原理说了这么多,那么闭包原理是什么?慢慢地听我说。看过我上一篇博客的朋友都知道,要想访问一个变量,就必须在这个变量的范围内。比如在闭包函数中定义了变量fronted,那么闭包函数中的匿名函数就可以访问fronted变量。因为只能访问父域或同域中的变量。当匿名函数在自身内部访问这个变量时,相当于持有了这个变量的引用,所以当匿名函数返回时,仍然可以访问这个变量。闭包有什么用?当技术出现的时候,为了解决一类问题,闭包能用来做什么?隐藏变量通过闭包,我们可以向外界输出一个变量,但不是直接暴露出来,而是通过一个类似接口的函数,让外界可以访问到变量,保证变量不被破坏.模块化的始祖按照笔者的理解,JavaScript的模块化是通过借用闭包来实现的。导入导出是通过定义一个模块变量并暴露相关操作模块方法来实现的。使用闭包的注意点一般来说,当一个函数运行结束后,函数中的变量内存会被回收,但是之前的博客特别强调过闭包不是这样的。其实如例子所示,即使闭包函数运行完毕,其返回的匿名函数仍然持有对变量fronted的引用,所以这个变量会一直存在于内存中,不会被回收(不是人为解引用)).因此可以预见的猜测,如果我们在程序中使用了大量的闭包,那么内存中就会存在大量的变量,占用前端的内存资源,从而导致性能下降。所以我们在开发过程中要慎用闭包。