码迷,mamicode.com
首页 > 其他好文 > 详细

浅谈闭包

时间:2018-05-23 23:34:48      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:点击事件   垃圾回收机制   fun   思考   应该   执行环境   结果   element   概念   

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

<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和其他命名参数的值来初始化函数的活动对象。

浅谈闭包

标签:点击事件   垃圾回收机制   fun   思考   应该   执行环境   结果   element   概念   

原文地址:https://www.cnblogs.com/wwx875075608/p/9080077.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!