浅谈闭包

Posted 天马行空的Max

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅谈闭包相关的知识,希望对你有一定的参考价值。

本文是从匿名函数、立即调用函数、作用域、作用域链、闭包的创建和销毁讨论关于闭包,想弄懂闭包这些都是我们想思考的。
对于闭包,我们应该先思考,为什么我们需要闭包。
举一个非常常见的例子:

<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>


var li=document.getElementsByTagName(‘li‘);

for(var i=0;i<6;i++){
  li[i].onclick=function(){
    console.log(i);
  }
}
这种情况下当然不行,因为如果你看到我的回答,相信你肯定看过n个类似的了。这是给每一个li都加上点击事件,点击后执行各自的匿名函数(虽然此处他们长得都一样),会触发各自的console,这时候就需要去找i,就去沿着作用域链去找,首先先咋i本身click事件的活动对象中找,找不到,继续往上找呗,找到全局变量对象,结果找到了,但这时候i已经在一次又一次的for循环中变成了6,所以就会输出6.

用两种闭包解决这个问题:

for(var i=0;i<6;i++){
  li[i].onclick=(function(i){
    return function(){
      console.log(i);
    }
  })(i)
}

for(var i=0;i<6;i++){
  (function(i){
    li[i].onclick=function(){
      console.log(i);
    }
  })(i)
}

li[0].onclick=null;//清除li[0]的闭包事件

问题解决了,但我们对于闭包的探究不该就此而止。
不知道大家有没有    匿名函数,立即执行函数     的概念。顾名思义
看我下面写的,也达到了想要的效果。大家可以结合起来的想一想。在这个例子中到底哪部分才是闭包的核心!我们到底是要把什么保存起来,怎么保存起来,不让js销毁机制销毁,达到我们想要的效果。

function test(i){
  li[i].onclick=function(){
    console.log(i);
  }
}
for(var i=0;i<6;i++){
  test(i);
}
我们要知道为什么不是闭包的函数会被js垃圾回收机制销毁,而闭包却可以存活下来。
网上所有的文章都在强调作用域和作用域链,当然我所看的JS高级程序设计中提到:有关如何创建作用域链以及作用域链有什么作用的细节,对彻底理解闭包至关重要。


在非闭包情况下,一个函数执行的过程中,会创建一个执行环境及其相应的作用域链,然后使用arguments和其他命名参数的值来初始化函数的活动对象。

以上是关于浅谈闭包的主要内容,如果未能解决你的问题,请参考以下文章

浅谈闭包

浅谈闭包

浅谈JavaScript--闭包

浅谈js闭包

浅谈闭包

浅谈JS闭包