当前位置: 首页 > 后端技术 > PHP

五分钟带你学会JavaScript闭包

时间:2023-03-30 06:17:48 PHP

闭包,这是javascript中特有的概念。对于初学者来说,闭包是一个特别抽象的概念,尤其是ECMA规范给出的定义。如果你没有实践经验,你很难从定义上理解它。所以本文不会大篇幅讲述闭包的概念,直接贴干货,让你分分钟学会闭包!1封闭——爱的初体验当我接触到一项新技术时,我首先要做的事情之一就是:找到它的演示代码。对于编码人员来说,代码有时比自然语言更能理解一件事。事实上,闭包无处不在。比如jQuery和zepto的主要代码都包含在一个大的闭包里面,那我就先写一个最简单最原始的闭包demo,让大家脑洞大开生成闭包:functionA(){functionB(){console.log("你好闭包!");}returnB;}varc=A();c();//你好闭包!这是有史以来最简单的闭包,再简单不过了,再简单也不是闭包!有了初步了解后,我们再简单分析一下它与普通函数的区别,让我们从“人山人海”中一眼认出“她”。上面的代码翻译成自然语言如下:(1)定义一个普通函数A(2)在A中定义一个普通函数B(3)returnsBinA(准确地说,返回A中B的引用)(4)执行A(),将A的返回结果赋值给变量c(5)执行c()将这5步操作总结成一句废话:函数A的内部函数B被变量c引用outsidefunctionA把这句废话再处理一下就变成了闭包的定义:当一个内部函数被除它的外部函数以外的变量引用时,就形成了一个闭包。不要刻意记住这个定义。告诉你这个定义的目的是让你明白上面的5步操作是为了解释闭包的定义。因此,当你执行了上面的5个步骤后,你就定义了一个闭包!这是关闭。2闭包的作用在理解闭包的作用之前,我们先了解一下javascript中的GC机制:在javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收,否则这个对象会一直保存在内存中.上面的例子中,B定义在A中,所以B依赖于A,而外部变量c又引用了B,所以A被c间接引用,即A不会被GC回收,会一直存放在内存中间。为了证明我们的推理,上面的例子稍作改进:functionA(){varcount=0;函数B(){计数++;控制台日志(计数);}returnB;}//这里我补充大家推荐一个前端全栈开发交流圈:619586920突破技术瓶颈,提升思维能力varc=A();c();//1c();//2c();//3count在A中是一个变量,在B中改变了它的值,每执行一次函数B,count的值就会在原来的基础上加1。因此,A中的计数始终保存在内存中。这就是闭包的作用。有时我们需要在一个模块中定义这样一个变量:我们希望这个变量一直保存在内存中但不会“污染”全局变量。这时候,我们可以使用闭包来定义这个模块。这次给大家推荐一个免费的学习圈,总结了移动应用网站开发,css,html,webpack,vuenodeangular,面试资源。获取信息???对web开发技术感兴趣的同学:???加入???,无论小白还是大牛,我都欢迎你,还有大牛整理的一套高效的学习路线和教程。你免费分享,每天更新视频素材。3高端写法上面的写法其实是最简单最原始的写法,但是在实际应用中,没有人这么玩,尤其是在一些大型的JS框架中。之所以还告诉你这种写法,是因为分心的因素越少,越容易专注于一件事。下面我用通常的写法写了一个简单的demo组件::function(child){viewport.appendChild(child);},removeChild:function(child){viewport.removeChild(child);}}//这里推荐一个前端全栈开发交流圈:619586920突破技术瓶颈,提高思维能力window.jView=obj;})(document);该组件的作用是初始化一个容器,然后向这个容器中添加子容器,或者移除一个容器。函数很简单,但是这里涉及到另外一个概念:立即执行函数。简单理解一下。主要是理解这种写法是如何实现闭包功能的。1上面的代码结构可以分为两部分:(function(){})()红色部分是一个表达式,而这个表达式本身就是一个匿名函数,所以在这个表达式后面加上()就是执行这个匿名函数。因此,这段代码的执行过程可以分解为:varf=function(document){varviewport;varobj={init:function(id){viewport=document.querySelector("#"+id);},addChild:function(child){viewport.appendChild(child);},removeChild:function(child){viewport.removeChild(child);}}//这里推荐一个前端全栈开发交流圈:619586920突破技术瓶颈,提升思维能力window.jView=obj;};f(document);在这段代码中,似乎看到了闭包的影子,但是f中没有返回值,似乎不满足闭包的条件,注意这段代码:window.jView=obj;obj是f中定义的一个对象,在这个对象中定义了一系列的方法。执行window.jView=obj就是在window全局对象中定义一个变量jView,并将这个变量指向obj对象,即全局变量jView引用obj。obj对象中的函数也引用了f中的变量viewport,所以f中的viewport不会被GC回收,会一直保存在内存中,所以这种写法满足了关闭条件的要求。4简单总结这是对闭包最简单的理解。当然,闭包也有更深层次的理解。这涉及到很多。你需要了解JS的执行环境(executioncontext)、活动对象(callobject)以及作用域(scope)和作用域链(scopechain)的运行机制。但是作为初学者,暂时不需要了解这些。有了简单的了解之后,就要在实际项目中使用了。当你用的多了,自然会对闭包有更深的理解!这次给大家推荐一个免费的学习圈,总结了移动应用网站开发,css,html,webpack,vuenodeangular,面试资源。获取信息???对web开发技术感兴趣的同学:???加入???,无论小白还是大牛,我都欢迎你,还有大牛整理的一套高效的学习路线和教程。你免费分享,每天更新视频素材。