• JavaScript闭包


    闭包其实就是利用了函数作用域和匿名函数的知识,当函数A执行结束时,一部分变量变量被B引用,被引用的变量不能释放,形成了所谓的闭包。这里有篇很好的文章,可以参考一下。
    下面看一个小例子:
    <script language="javascript" type="text/javascript">
    function show(){
        var n=3;
        setTimeout(function(){alert("first:"+n);},3000); //3秒后显示first:3
        alert("second:"+n); //显示second:3
    }
    show();
    function show2(){alert("第一个函数执行结束");}
    show2();
    </script>

    运行上面的函数后,首先alert显示"second:3",然后显示"第一个函数执行结束",3秒后显示“first:3”。

    仔细看一下,函数show执行结束的时候,变量n应该被释放了,内存里也就不存在了,怎么过了3秒还能显示出"first:3"呢?闭包恰恰就在此产生了,当函数show执行结束的时候,想要释放内存里的n,但发现变量n还在被一个匿名函数引用,要在3秒后调用,根据JavaScript闭包原理,内存里的n被保留了下来,于是在三秒以后仍然可以调用n。
    下面看几种写法的区别:

    function show2(content){
      alert(content);  //3秒后alert显示"test"
    }
    function show(content,delay_time){
        setTimeout("show2('"+content+"')",delay_time);
    }
    show("test",3000);
    仔细看一下上面这种写法不是闭包,只是普通的函数调用而已。
    function show(content,delay_time){
        setTimeout(function(){alert(content)},delay_time); //3秒后alert显示"test"
    }
    show("test",3000);

    这种写法就是闭包,虽然结果是一样的,但原理不一样。
    function show(content){
        function show2(){alert(content);}
        return show2;
    }
    var newshow=show("test");
    setTimeout(newshow,3000);  //3秒后alert显示"test"

    上面这种写法也是闭包,虽然结果都是一样的,但原理却不一样。这里面看到了函数也可以当作对象也传递,函数show执行后return show2,把函数show2赋值给newshow,然后3秒后,调用newshow对象,执行函数show2。
    仔细比较上面3种写法,如果能悟出一些道理就好,闭包有些时候的确难理解。
    稍复杂一点的例子:
    <script language="javascript" type="text/javascript">
    var show=null;
    (function(){
      var n=1;
      var show2=function(){
          alert(n++);
      }
      show=show2;
    })();

    show();  //显示1
    show();  //显示2
    show();  //显示3
    </script>

    上面代码中,又一次用了函数作为对象传递,n是匿名函数里的局部变量,外部是访问不到的。show是一个全局变量,应该访问不了变量n,但在函数show执行前,首先把函数匿名函数内部show2赋值给show,当后面函数show运行的时候,会调用show2的代码,而show2是可以访问n的,故结果显示为1、2、3。

    CSS代码:

    ul{ 600px; margin:0px auto;}
    ul li{ margin:1px 0px; }
    HTML代码:
    <ul>
      <li>1</li>
      <li>2</li>
      <li>3</li>
      <li>4</li>
    </ul>
    JavaScript代码:
    <script language="javascript" type="text/javascript">
    var li=document.getElementsByTagName("li");
    for(var i=0;i<li.length;i++){
       li[i].onclick=function(){alert(i);}
    }
    </script>

    运行后,不论点击哪一个li,都是alert提示“4”。这就是一个需要注意的地方:闭包允许内层函数引用父函数中的变量,但是该变量是最终值。闭包引用的变量i,是循环结束后的值,其实这是一个很常见的问题。
    比较常见的就是给li[i]添加属性值,比如li[i].n=i;还有就是用闭包方法解决,这个函数本身就是闭包,所谓用闭包来解决闭包的问题。代码如下:

    <script language="javascript" type="text/javascript">
    var li=document.getElementsByTagName("li");
    for(var i=0;i<li.length;i++){
       (function(index){
       li[index].onclick=function(){alert(index);}
       })(i); 
    }
    </script>
  • 相关阅读:
    Thread的run方法和start方法
    35. Search Insert Position
    Error:(1, 1) java: 非法字符: 'ufeff'
    final修饰的变量是引用不可变,还是对象不可变
    数组与练习
    java反射机制【转】
    Socket
    面向对象的设计原则和设计模式
    多线程
    为什么有时候修改了css文件,页面的样式却没有改变?
  • 原文地址:https://www.cnblogs.com/littlewriter/p/6050908.html
Copyright © 2020-2023  润新知