闭包有多重要?如果你是初入前端的朋友,我没有办法直观的告诉你闭包在实际开发中的无处不在,但是我可以告诉你,前端面试,必问闭包。面试官们常常用对闭包的了解程度来判定面试者的基础水平,保守估计,10个前端面试者,至少5个都死在闭包上。
面试之作用域链与闭包
作用域链【主要作用:变量名解析】
如果你理解了作用域链,那么闭包对于你而言,理解起来就相当地简单了。
作用域链,当然可以看成是一个(有序检索)的对象列表。
有序检索:即就近原则“由近及远”,全所以大家一定要明白局对象始终是最后一个!
举例来说,也就是:
假如JS的顶级代码(不包含在函数内的代码),它的作用域链就是一个全局对象;
假如JS代码中有函数,但是没嵌套,它的作用域链有两个对象,第一个是函数内的变量即函数参数,第二个就是全局对象【第一第二的顺序很重要】;
假如有函数嵌套,那么作用域链至少有3个对象。
了解完作用域链的主要作用,这个时候我们就要知道它的【创建规则】
定义函数的时候,会保存一个作用域链;
调用函数的时候,有两个操作:一是将函数内的局部变量保存在一个新建对象中,然后添加到函数定义时的作用域链中;二是会创建一个“运行期上下文”的内部对象,每一个运行期上下文都有一个单独的作用域链,而调用时会将上面提到那个作用域链中的对象相当于复制一份到运行期上下文这个作用域链中。
在嵌套函数时,有些不一样,我们每一次调用外部函数的时候,内部函数都需要重新定义一次,因为每次运行外部函数时,它的作用域链都是不相同的。内部函数在每次定义时也有微妙的差别——在每次调用外部函数的时候,内部函数的代码是相同的,而且关联这段代码的作用域链也不相同。
function buttonInit(){ for(var i=1;i<4;i++){ var b=document.getElementById("button"+i); b.addEventListener("click",function(){ alert("Button"+i); },false); } }window.=buttonInit;//--结果:都是button4function buttonInit(){ for(var i=1;i<4;i++){ (function a(j) { console.log(j); var b=document.getElementById("button"+j); b.addEventListener("click",function(){ alert("Button"+j); },false); })(i) } }window.=buttonInit;//--结果:button1、button2、button3
闭包:【主要作用:变量私有化】
缺点:
1、 闭包会让函数内部变量始终保存在内存中,需要手动释放资源;
【解决办法:即将函数设置为null】
2、过多的闭包导致内存泄漏。
实现闭包:
当嵌套函数被作为外部函数的返回值返回或者存储在某处的属性里,这时会有一个外部引用指向这个嵌套函数,就不会被回收,并且这个嵌套函数所指向的变量绑定对象也不会回收。
function buttonInit(){ for(var i=1;i<4;i++){ var b=document.getElementById("button"+i); b.addEventListener("click",function(){ alert("Button"+i); },false); } }window.=buttonInit;//--结果:都是button4function buttonInit(){ for(var i=1;i<4;i++){ (function a(j) { console.log(j); var b=document.getElementById("button"+j); b.addEventListener("click",function(){ alert("Button"+j); },false); })(i) } }window.=buttonInit;//--结果:button1、button2、button3
作者:前端攻城小牛
链接:https://www.jianshu.com/p/45ec2b6b8ff3
共同学习,写下你的评论
评论加载中...
作者其他优质文章