zoukankan      html  css  js  c++  java
  • 详解javascript闭包特性

    闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。

    闭包有三个特性:
    1.函数嵌套函数
    2.函数内部可以引用外部的参数和变量
    3.参数和变量不会被垃圾回收机制回收

    闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量

    使用闭包有一个优点,也是它的缺点,就是可以把局部变量驻留在内存中,可以避免使用全局变量。全局变量在每个模块都可调用,这势必将是灾难性的。

    所以推荐使用私有的,封装的局部变量。

    一般函数执行完毕后,局部活动对象就被销毁,,内存中仅仅保存全局作用域。但闭包的情况不同!

     1 function aaa() {  
     2       var a = 1;  
     3       return function(){
     4 alert(a++)
     5   };  
     6     }         
     7     var fun = aaa();  
     8     fun();// 1 执行后 a++,,然后a还在~  
     9     fun();// 2   
    10     fun = null;//a被回收!!  

    嵌套函数的闭包

     1 <script>
     2 function outer(){                         //外部函数
     3         var a = 5;
     4         function inner(){                         //内部函数
     5                 alert(a);
     6         }
     7         return inner;                             //返回内部函数,也可以写成return inner();
     8 }
     9 
    10 var c = outer();                       
    11 c();                                       //调用外部函数,开始执行
    12 </script>

    以上输出结果为5;
    闭包会使变量始终保存在内存中,如果不当使用会增大内存消耗。
    javascript的垃圾回收原理
    (1)、在javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收;
    (2)、如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。


    那么使用闭包有什么好处呢?使用闭包的好处是:
    1.希望一个变量长期驻扎在内存中
    2.避免全局变量的污染
    3.私有成员的存在

    一、全局变量的累加

    1 <script>
    2 var a = 1;
    3 function abc(){
    4         a++;
    5         alert(a);
    6 }
    7 abc();              //2
    8 abc();            //3
    9 </script>

    二、局部变量

     1 <script>
     2 
     3 function abc(){
     4         var a = 1;
     5         a++;
     6         alert(a);
     7 }
     8 abc();                       //2
     9 abc();                    //2
    10 </script>

    那么怎么才能做到变量a既是局部变量又可以累加呢?

    三、局部变量的累加(闭包所能做到的)

     1 <script>
     2 function outer(){
     3         var x=10;
     4         return function(){             //函数嵌套函数
     5                 x++;
     6                 alert(x);
     7         }
     8 }
     9 var y = outer();              //外部函数赋给变量y;
    10 y();                 //y函数调用一次,结果为11
    11 y();                //y函数调用第二次,结果为12,实现了累加
    12 </script>

    js中的函数声明与函数表达式:
    在js中我们可以通过关键字function来声明一个函数:

    1 <script>
    2 function abc(){
    3         alert(123);
    4 }
    5 abc();
    6 </script>

    我们也可以通过一个"()"来将这个声明变成一个表达式:

    1 <script>
    2 (function (){
    3         alert(123);
    4 })();                   //然后通过()直接调用前面的表达式即可,因此函数可以不必写名字;
    5 </script>

    四、模块化代码,减少全局变量的污染

     1 <script>
     2 var abc = (function(){      //abc为外部匿名函数的返回值
     3         var a = 1;
     4         return function(){
     5                 a++;
     6                 alert(a);
     7         }
     8 })();
     9 abc();    //2 ;调用一次abc函数,其实是调用里面内部函数的返回值    
    10 abc();    //3
    11 </script>

    五、私有成员的存在

     1 <script>
     2 var aaa = (function(){
     3         var a = 1;
     4         function bbb(){
     5                 a++;
     6                 alert(a);
     7         }
     8         function ccc(){
     9                 a++;
    10                 alert(a);
    11         }
    12         return {
    13                 b:bbb,             //json结构
    14                 c:ccc
    15         }
    16 })();
    17 aaa.b();     //2
    18 aaa.c()      //3
    19 </script>

    七、在循环中直接找到对应元素的索引

     1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     2 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
     3 <head>
     4         <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
     5         <title></title>
     6 <script>
     7 window.onload = function(){
     8         var aLi = document.getElementsByTagName('li');
     9         for (var i=0;i<aLi.length;i++){
    10                 aLi[i].onclick = function(){        //当点击时for循环已经结束
    11                 alert(i);
    12                 };
    13         }
    14 }
    15 </script>
    16         
    17 </head>
    18 <body>
    19         <ul>
    20                 <li>123</li>
    21                 <li>456</li>
    22                 <li>789</li>
    23                 <li>010</li>
    24         </ul>
    25 </body>
    26 </html>
    — — — — 在人生的道路上,我们需要用行动来证明和兑现曾经心动过的梦想!— — — —
  • 相关阅读:
    zoj 3279 线段树 OR 树状数组
    fzu 1962 树状数组 OR 线段树
    hdu 5057 块状链表
    hdu3487 Play with Chain
    bzoj 1588营业额统计(HNOI 2002)
    poj2823 Sliding Window
    poj2828 Buy Tickets
    poj2395 Out of Hay
    poj3667 Hotel
    poj1703 Lost Cows
  • 原文地址:https://www.cnblogs.com/trigkit4/p/3915386.html
Copyright © 2011-2022 走看看