zoukankan      html  css  js  c++  java
  • JavaScript闭包理解【关键字:普通函数、变量访问作用域、闭包、解决获取元素标签索引】

        一、闭包(Closure)模糊概述

    之前总觉得闭包(Closure)很抽象而且难理解,百度一下"闭包"名词,百度的解释是:“闭包是指可以包含自由(未绑定到特定对象)变量的代码块;这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)”

    看了半天,也没有看懂闭包是什么?以下将是我对闭包(Closure)的理解,如有错误欢迎指出

        二、普通函数、变量访问作用域

    以上普通函数的调用fn被调用了两次,变量b却没有累加??

    对于函数f1变量b在函数外部是不能访问的

    如若实现局部变量b的累加,并且可以访问该怎么做呢?

        三、闭包(Closure)的清晰描述

    (1)闭包(Closure)简单的可以理解成函数的嵌套,闭包就是能够读取其他函数内部变量的函数。

    (2)变量长期驻留在内存中

    以上可以看出,父函数f1中的变量b对于子函数f2是可访问的或者说是可见的,父函数f1调用一次,意味着变量b始终都是同一变量,f2中的b++,实现了对同一变量的自加,

    对于子函数f2形成一个最简单的闭包(或者说函数f2维持着对外部作用域f1的引用,因此总可以访问f1作用域中的变量b)

        三、闭包在对象中应用

        四、解决获取标签索引问题

       需求:当点击点击标签li时,获取标签li的内容及索引

     a.理想中的方案一<未使用闭包,未解决索引值问题>

    效果:未解决获取到当前点击标签对应索引值,获取到的索引总是for循环完毕后的索引i

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>未使用闭包获取标签索引</title>
     6     <script type="text/javascript">
     7         window.onload=function(){
     8             var oLi=document.getElementsByTagName('li');
     9             for (var i = 0; i < oLi.length; i++) {
    10                 oLi[i].onclick=function(){//当点击li的时候,for循环已经执行完毕
    11                     alert(this.innerHTML+'index'+i);//总是i==5
    12                 }
    13             };
    14         }
    15     </script>
    16 </head>
    17 <body>
    18     <ul>
    19         <li>AAA</li>
    20         <li>BBB</li>
    21         <li>CCC</li>
    22         <li>DDD</li>
    23         <li>EEE</li>
    24     </ul>
    25 </body>
    26 </html>

       b.解决方案二<使用闭包>代码如下:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>闭包解决获取标签索引问题</title>
     6     <script type="text/javascript">
     7         window.onload=function(){
     8                 var oLi=document.getElementsByTagName('li');
     9                 /*for (var i = 0; i < oLi.length; i++) {
    10                     oLi[i].onclick=(function(i){ //就已经存储到缓冲中
    11                        return function(){
    12                             alert(this.innerHTML+'index'+i);
    13                        }
    14                     })(i)
    15                 };*/
    16                 for (var i = 0; i < oLi.length; i++) {
    17                     (function(i){
    18                         oLi[i].onclick=function(){
    19                             alert(this.innerHTML+'index'+i);
    20                         }
    21                     })(i)
    22                 };
    23         }
    24     </script>
    25 </head>
    26 <body>
    27     <ul>
    28         <li>AAA</li>
    29         <li>BBB</li>
    30         <li>CCC</li>
    31         <li>DDD</li>
    32         <li>EEE</li>
    33     </ul>
    34 </body>
    35 </html>

        五、一道思考题(for循环与setTimeout)

    上述打印结果打印了10次10,而不是0~9

    原因 当 console.log 被调用的时候,匿名函数保持对外部变量 i 的引用,此时 for循环已经结束, i 的值被修改成了 10.

    为了打印结果是0~9,需要在每次循环时创建变量i的拷贝改代码如下

    或修改成如下

    作者:Avenstar

    出处:http://www.cnblogs.com/zjf-1992/p/5380456.html

    关于作者:专注于前端开发、喜欢阅读

    本文版权归作者所有,转载请标明原文链接

    资料参考

     http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html

     http://www.jb51.net/onlineread/JavaScript-Garden-CN/#function.closures

  • 相关阅读:
    张礼鑫(帮别人名字作诗)
    千年的守望
    感恩
    转载:像成功人士一样释放压力,快乐并高效着
    50个MBA精粹 [推荐]
    赚钱不是人生的全部
    世界上最权威的68句创业名言,哪一句让你获益匪浅
    郝雪涛只爱薛乙静(帮恋人名字作诗)
    心爱的,你为何还不来为我们的爱情赴约
    中国,请还我一个诗的天堂
  • 原文地址:https://www.cnblogs.com/zjf-1992/p/5380456.html
Copyright © 2011-2022 走看看