zoukankan      html  css  js  c++  java
  • Javascript关闭详细说明

    在我的博客:http://blog.csdn.net/u011043843/article/details/26148265  中也有对闭包的解释


    在javascript中闭包是一个非常不好理解的概念。可是确实一个不可逃避的东西,那么今天我们就来一起学习一下闭包。

             

            什么是闭包?

            闭包:官方的解释是:闭包是一个拥有很多变量和绑定了这些变量的环境的表达式(一般是一个函数),因而这些变量也是该表达式的一部分。

    相信读完这句话以后,你就更加不知道什么是闭包了。

    事实上通俗的说闭包就是一个函数a内部的局部变量s,被该函数内部的函数b所使用,而且a函数返回值为b函数。

    那么我们就将b函数成为闭包。


            为什么会产生闭包这个概念呢?那就要谈谈变量作用域的问题了。

            变量的作用域无非就是两种:全局变量和局部变量。

            Javascript语言的特殊之处,就在于函数内部能够直接读取全局变量。


            Js代码

    [javascript] view plaincopy在CODE上查看代码片派生到我的代码片
    1. <span style="font-size:18px;">var n=999;  
    2. function f1(){  
    3.     alert(n);  
    4. }  
    5. f1(); // 弹出对话框:999</span>  

            还有一方面,在函数外部自然无法读取函数内的局部变量。

            Js代码

    [javascript] view plaincopy在CODE上查看代码片派生到我的代码片
    1. functionf1(){  
    2.     varn=999;  
    3. }  
    4. alert(n); //弹出对话框:error  

             这里有一个地方须要注意,函数内部声明变量的时候。一定要使用var命令。假设不用的话,你实际上声明了一个全局变量!

             Js代码

    [javascript] view plaincopy在CODE上查看代码片派生到我的代码片
    1. <span style="font-size:18px;">functionf1(){  
    2.    n=999;  
    3. }  
    4. f1();  
    5. alert(n); //999</span>  

             那么怎样从外部读取局部变量?

             出于种种原因,我们有时候须要得到函数内的局部变量。可是,前面已经说过了,正常情况下,这是办不到的。仅仅有通过变通方法才干实现。那就是在函数的内部,再定义一个函数。

            Js代码

    [javascript] view plaincopy在CODE上查看代码片派生到我的代码片
    1. <span style="font-size:18px;">functionf1(){  
    2.     varn=999;  
    3.     functionf2(){  
    4.         alert(n); // 999  
    5.     }  
    6. }</span>  

            在上面的代码中,函数f2就被包含在函数f1内部,这时f1内部的全部局部变量,对f2都是可见的。可是反过来就不行,f2内部的局部变量,对f1 就是不可见的。这就是Javascript语言特有的“链式作用域”结构(chainscope)。子对象会一级一级地向上寻找全部父对象的变量。所以,父对象的全部变量,对子对象都是可见的,反之则不成立。

           既然f2能够读取f1中的局部变量,那么仅仅要把f2作为返回值,我们不就能够在f1外部读取它的内部变量了吗!

           Js代码

    [javascript] view plaincopy在CODE上查看代码片派生到我的代码片
    1. <span style="font-size:18px;">functionf1(){  
    2.     varn=999;  
    3.     functionf2(){  
    4.        alert(n);  
    5.     }  
    6.     returnf2;  
    7. }  
    8. varresult=f1();  
    9. result(); //999</span>  

           这个我们在函数函数f1的外部就能够读取到f1内的变量n的值了。

           大家可能注意到了,这个函数函数跟我上边的描写叙述好像非常吻合,没错。这就是闭包了。

           那么总结一下闭包都具备哪些特点呢?

           1,闭包外层是个函数.
           2,闭包内部都有函数.
           3,闭包会return内部函数.
           4,闭包返回的函数内部不能有return.(由于这样就真的结束了)


           闭包有什么作用呢?

           一个是像上边所说的那样,在函数外边訪问函数内部的变量。

    还有一个就是让这些变量的值始终保持在内存中

    怎么理解他的第二个作用呢?

          看一下下边这个样例:

    [javascript] view plaincopy在CODE上查看代码片派生到我的代码片
    1. <span style="font-size:18px;">Js代码  
    2. functionf1(){  
    3.     varn=999;  
    4.     functionf2(){  
    5.         alert(++n);  
    6.     }  
    7.     returnf2;  
    8. }  
    9. varresult=f1();  
    10. result(); // 999  
    11. result(); //1000</span>  

            大家能够看到两次运行同一个函数,结果却是不一样的。这个是为什么呢?为什么不像其它语言那个。一个函数运行完以后就被垃圾机制回收呢? 原因就在javascript的垃圾回收机制中,在Javascript中,假设一个对象不再被引用,那么这个对象就会被GC回收。

    假设两个对象互相引用,而不再被第3者所引用。那么这两个互相引用的对象也会被回收。由于函数f1被f2引用,f2又被f1外的c引用,这就是为什么函数f1运行后不会被回收的原因。


             使用闭包函数应该注意的问题;

             1)因为闭包会使得函数中的变量都被保存在内存中。内存消耗非常大,所以不能滥用闭包。否则会造成网页的性能问题。在IE中可能导致内存泄露。解决方法是,在退出函数之前。将不使用的局部变量所有删除。

             2)闭包会在父函数外部。改变父函数内部变量的值。

    所以,假设你把父函数当作对象(object)使用。把闭包当作它的公用方法(PublicMethod)。把内部变量当作它的私有属性(privatevalue),这时一定要小心。不要随便改变父函数内部变量的值。


             闭包(closure)是Javascript语言的一个难点。也是它的特色,非常多高级应用我们必须依靠实现截流.所以,我们学到的道路,以高数量倒闭js只有这样,人猿的节目。

    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    bzoj1415 NOI2005聪聪和可可
    Tyvj1952 Easy
    poj2096 Collecting Bugs
    COGS 1489玩纸牌
    COGS1487 麻球繁衍
    cf 261B.Maxim and Restaurant
    cf 223B.Two Strings
    cf 609E.Minimum spanning tree for each edge
    cf 187B.AlgoRace
    cf 760B.Frodo and pillows
  • 原文地址:https://www.cnblogs.com/hrhguanli/p/4737899.html
Copyright © 2011-2022 走看看