zoukankan      html  css  js  c++  java
  • 夺命雷公狗---javascript NO:30 闭包

    1、什么是闭包

    所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。

    例1:运行一下代码,得出结论:在全局作用域没有办法直接引用局部变量

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset=’utf-8′>
    <title></title>
    </head>
    <body>
    <script>
    function display(){
    var i = 10;//局部变量
    }
    display();
    alert(i);  //报错
    </script>
    </body>
    </html>

    原因:1)作用域不允许

    2)受到js的垃圾回收影响

    例2:有没有办法实现在全局作用域中引用局部变量,运行一下代码

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset=’utf-8′>
    <title></title>
    </head>
    <body>
    <script>
    function display(){
    var i = 10;  //局部变量
    function fn(){
    alert(‘hello’);
    }
    return fn;  //返回fn函数的首地址
    }
    var test = display();  //定义一个test全局变量,实现display进行引用==>var test =fn;
    test();  //hello
    </script>
    </body>
    </html>

    通过运行可知,以上代码可以正常弹出hello字符串,那么这是不是和我们js的垃圾回收所冲突呢?答:不冲突,原因如下:

    当我们把display函数的返回值赋值给全局test全局变量时,相当于把fn的函数的首地址赋值给test全局变量,那么在全局中就会有一个引用关系引用了局部函数fn,当js垃圾回收机制运行时,发现fn函数受到了全局变量的引用,所以并不会回收局部函数fn,所以以上代码可以正常弹出hello字符串。

    2、JavaScript中的垃圾回收机制

    在内存中有一个引用计数器,如果外部对这块内存有引用,那么引用计数器会自动进行+1操作,当js的垃圾回收机制运行时,如果引用计数器为0,那么会自动回收此内存空间,反之则不清理。

    3、闭包的小故事

    很久很久以前,有一对姐妹:大桃红、小桃红

    小桃红穿越到了清朝,见了传说中四阿哥,又和宫中宫女以及福晋以姐妹相称

    有一天:四阿哥问小桃红:“你的姐姐是谁?”,答:“大桃红”

    其实闭包也是这样一个概念。

    • 闭包即 函数定义时,连同其定义环境的上下文,形成一个整体
    • 不管该函数在哪儿运行,其对变量的访问,都要从定义处开始寻找

    4、我们眼中的闭包函数

    1)函数中的函数

    2)把内部函数的首地址作为函数返回值

    5、闭包的作用

    1)可以在全局作用域中访问局部变量

    2)使局部变量一直驻留在计算机的内存中

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset=’utf-8′>
    <title></title>
    </head>
    <body>
    <script>
    function display(){
    var i = 10;
    function fn(){
    alert(++i);
    }
    return fn;
    }
    var test = display();
    test();//11
    test();//12
    test();//13
    test();//14
    </script>
    </body>
    </html>

    注:虽然闭包非常好用且可以让我们访问局部变量,但是不推荐大家使用闭包程序,由于闭包会一直导致局部变量以及闭包不能被JavaScript垃圾回收机制所回收,所以可能会产生内存泄漏,能不用尽量不用,特殊情况除外。

  • 相关阅读:
    @@@并发实战
    @@@jvm实战
    @@@spring Boot环境下dubbo+zookeeper实战
    FastJson 支持配置的PropertyNamingStrategy四种策略
    利用MySQL统计一列中不同值的数量方法示例
    Springboot+websocket+定时器实现消息推送
    Spring AOP中args()、arg-names、argNames
    squid,nginx,lighttpd反向代理的区别
    HashMap底层实现原理/HashMap与HashTable区别/HashMap与HashSet区别
    HTTP 错误 500.24
  • 原文地址:https://www.cnblogs.com/leigood/p/5032025.html
Copyright © 2011-2022 走看看