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

javascript中closure闭包详解

时间:2023-04-03 16:35:11 Node.js

简介Closure闭包是javascript中一个非常强大的功能。所谓闭包就是函数中的函数。内部函数可以访问外部函数的作用域,这样闭包就可以用来做一些强大的工作。今天就给大家详细介绍一下闭包。函数中的函数我们提到函数中的函数可以访问父函数范围内的变量。让我们看一个例子:functionparentFunction(){varaddress='flydean.com';函数alertAddress(){警报(地址);}alertAddress();}parentFunction();在上面的例子中,我们在parentFunction中定义了一个变量address,在parentFunction内部定义了一个alertAddress方法,在这个方法内部访问了外部函数中定义的address变量。上面代码运行良好,可以正确访问数据。Closure闭包函数中有函数,那么什么是闭包呢?让我们看下面的例子:functionparentFunction(){varaddress='flydean.com';函数alertAddress(){警报(地址);}返回警报地址;}varmyFunc=parentFunction();myFunc();一个例子很相似,不同的是我们返回了内部函数,并赋值给了myFunc。接下来我们直接调用myFunc。在myFunc中访问parentFunction中的address变量,虽然parentFunction已经执行并返回。但是当我们调用myFunc时,我们仍然可以访问地址变量。这是关闭。闭包的这个特性很好,我们可以使用闭包来生成函数工厂,如下:functionmakeAdder(x){returnfunction(y){returnx+y;};}varadd5=makeAdder(5);varadd10=makeAdder(10);控制台日志(add5(2));//7console.log(add10(2));//12其中add5和add10是闭包,它们是由函数工厂makeAdder创建的。通过传递不同的x参数,我们可以为add方法获得不同的基数。最后生成了两种不同的add方法。使用函数工厂的概念,我们可以考虑闭包的实际应用。比如我们在页面上有三个按钮,点击这几个按钮就可以实现修改字体的功能。我们可以先通过函数工厂生成三个方法:functionmakeSizer(size){returnfunction(){document.body.style.fontSize=size+'px';};}varsize12=makeSizer(12);varsize14=makeSizer(14);varsize16=makeSizer(16);通过这三个方法,我们绑定DOM元素和回调方法:document.getElementById('size-12').onclick=size12;document.getElementById('size-14').onclick=size14;document.getElementById('尺寸16').onclick=size16;使用闭包实现私有方法与java相比,java中有私有访问描述符。通过private,我们可以指定该方法只能在类内部访问。当然在JS中是没有的,但是我们可以使用闭包来达到同样的效果。varcounter=(function(){varprivateCounter=0;functionchangeBy(val){privateCounter+=val;}return{increment:function(){changeBy(1);},decrement:function(){changeBy(-1);},值:function(){returnprivateCounter;}};})();console.log(counter.value());//0.counter.increment();counter.increment();控制台。日志(计数器值());//2.counter.decrement();console.log(counter.value());//1.我们在父函数中定义了privateCounter属性和changeBy方法,但是这些方法只能在内部函数中访问。我们通过闭包的概念,将这些属性和方法封装起来暴露给外部使用,最终达到封装私有变量和方法的效果。闭包的ScopeChain对每个闭包都有一个作用域,包括函数本身的作用域、父函数的作用域和全局作用域。如果我们在函数内部嵌入一个新的函数,就会形成一个作用域链,我们称之为作用域链。看下面的例子://globalscopevare=10;functionsum(a){returnfunction(b){returnfunction(c){//outerfunctionsscopereturnfunction(d){//localscopereturna+b+c+d+e;}}}}console.log(sum(1)(2)(3)(4));//log20commonproblemswithclosures第一个常见问题是在循环遍历中使用闭包,我们来看一个例子:varhelpText=[{'id':'email','help':'你的电子邮件地址'},{'id':'name','help':'你的全名'},{'id':'age','help':'你的年龄(必须年满16岁)'}];for(vari=0;i