zoukankan      html  css  js  c++  java
  • 闭包的理解

    1、什么是闭包?

    闭包就是指有权访问另一个函数作用域中变量的函数,通俗点讲闭包就是能够读取其他函数变量的函数。常见的构造方法,是在一个函数内部定义另外一个函数。内部函数可以引用外层的参数和变量;参数和变量不会被垃圾回收机制回收。除非用立即执行函数来解决。所以闭包的特性:

    (1)函数内再嵌套函数;

    (2)内部函数可以引用外层的参数和变量;

    (3)参数和变量不会被垃圾回收机制回收。

    复制代码
     1         function fn1() {
     2             var a = 1 ;
     3             function fn2() {
     4                 alert(a);
     5             }
     6             return fn2;
     7         }
     8 
     9         var result = fn1();
    10         result();  //1
    复制代码

    上述函数fn2就是一个闭包,我们可以通过返回fn2获取到fn1中的变量。

    2、闭包的用途

    (1)通过闭包去访问函数内部的变量;

    (2)使某些变量常驻内存。

    复制代码
     1         //没有闭包情况下变量a的情况
     2         function add() {
     3             var a = 1;
     4             a++;
     5             alert(a);
     6         }
     7         add();   //2
     8         add();   //2
     9 
    10         //有闭包的方式下
    11         function add2() {
    12             var a = 1;
    13             function fn() {
    14                 a++;
    15                 alert(a);
    16             }
    17             return fn;
    18         }
    19         var result = add2();
    20         result();  //2
    21         result();  //3
    复制代码

    在有闭包的情况下,result()的两次输出分别是2、3,这说明aad2中的a变量一直在内存当中,并没有因为add2的调用后被垃圾回收机制回收(garbage collection)。

    为什么会产生这样的情况?这是因为add2是fn的父亲函数,而在全局环境当中,fn其实是被赋给了全局变量result的,而result只会在全局环境执行完所有代码之后才会被回收,所以就导致了fn常驻内存,而fn的存在又依赖于父亲函数add2,所以add2在被调用之后也不会被GC(垃圾回收机制)回收,也始终存在于内存当中。

    3、闭包可能会引发的问题

    由于IE9之前的版本对JSript对象和COM对象使用了不同的垃圾回收机制,所以闭包在IE9之前的版本中会导致内存泄漏问题。具体来说就是,如果闭包中保存着一个HTML元素,那么这个元素将无法被销毁,直到退出程序或关闭浏览器。

    复制代码
    1     <script>
    2         window.onload = function () {
    3             var oBox = document.getElementById('box');
    4 
    5             oBox.onclick = function () {
    6                 alert(oBox.id);
    7             }
    8         };
    9     </script>
    复制代码

    像上述的情况下就发生了内存泄漏,因为在闭包中创建了一个循环引用。可以通过以下方法得到解决:

    复制代码
     1     <script>
     2         window.onload = function () {
     3             var oBox = document.getElementById('box');
     4 
     5             oBox.onclick = function () {
     6                 alert(oBox.id);
     7             };
     8 
     9             //方法一
    10             window.onunload = function () {
    11                 oBox.onclick = null;
    12             }
    13         };
    14 
    15         //方法二
    16         window.onload = function () {
    17             var oBox = document.getElementById('box');
    18             var id = oBox.id;
    19 
    20             oBox.onclick = function () {
    21                 alert(id);
    22             };
    23 
    24             oBox = null;
    25         };
    26         
    27     </script>
    复制代码

     

  • 相关阅读:
    小知识,大应用--正交向量在CDMA中的运用
    翻译:做好iPhone程序的10点建议
    解决了对多层结构一些疑惑,整理一下!
    原来是这样的——生活中的随笔
    3.14..............
    基础 - 结构
    推荐一本书《我编程,我快乐》
    基础 - 异常处理
    今天发现一个以前写的管理代码片段的程序,把源码发出来!
    VNC快速教程
  • 原文地址:https://www.cnblogs.com/manshufeier/p/9437352.html
Copyright © 2011-2022 走看看