zoukankan      html  css  js  c++  java
  • 再谈JavaScript的closure--JavaScript 闭包

    关于JavaScript的闭包,在我的博客上之前有一篇文章 https://www.cnblogs.com/wphl-27/p/8491327.html

    今天看了几篇文章,感觉又有了一些更深的理解,特记录如下:

    其实关于JavaScript的闭包closure, 简单点理解可以如下:

    在JavaScript中,一个函数A内部又包含一个函数B, 同时把内部函数B作为函数A的返回值,这个时候,就形成了一个闭包。

    我们来看一个简单的例子:

    var a = 5;
    
    function TestAdd(){
    
       return a += 5;
    
    }
    
    TestAdd();    // a = 10
    TestAdd();    // a = 15
    TestAdd();    // a = 20
    TestAdd();    // a = 25

    上面的JavaScript脚本例子中,我们定义了一个全局变量a, 在函数TestAdd中,对该全局变量a加5,由于a是一个全局变量,所以每调用一次TestAdd方法,就会往a上累加5

    我们的需求是: 如果需要更改a的值,则只能通过TestAdd这个方法来更改,不能通过其他途径来更改

    但是,我们看看上面的代码,实现了我们的需求吗? 我们确实可以通过TestAdd方法来更改a的值,但同时由于a是一个全局变量,我们在其他地方可以很容易的修改它的值,比如 a = 34;  所以,这个代码是达不到我们需求的

    现在我们对它进行修改,我们会很容易想到,既然需求是只能通过方法TestAdd来修改a的值,那么我们可以把变量a放到TestAdd内部去,代码如下

    function TestAdd(){
    
       var a = 5;
       return a += 5;
    
    }
    
    TestAdd();    // a = 10
    TestAdd();    // a = 10
    TestAdd();    // a = 10
    TestAdd();    // a = 10

    但是这样,我们发现,我们本来希望4次调用TestAdd方法后,输出的是25。但实际上输出的却是10. 因为现在a是函数TestAdd内部的局部变量,所以你每次调用TestAdd方法时,都会重新初始化a为5

    那么我们能如何解决这个问题呢,答案就是JavaScript Closure -- JavaScript 闭包, 代码如下

    var Testadd = (function(){
    
       var a = 5;
       return function(){
    
          return a += 5;
        }
    })();
    
    TestAdd();    // a = 10
    TestAdd();    // a = 15
    TestAdd();    // a = 20
    TestAdd();    // a = 25

    上面的TestAdd是自执行函数,当然我们也可以写成如下这样

    function myFunc(){
    
       var a = 5;
       return function(){
    
          return a += 5;
        }
    }
    
    var TestAdd = myFunc();
    
    TestAdd();    // a = 10
    TestAdd();    // a = 15
    TestAdd();    // a = 20
    TestAdd();    // a = 25

    可以看出,上面两种写法,TestAdd代表的都是内部返回的函数(闭包函数)function(){return a += 5;}  而它用到的这个变量a则是它的外部函数的变量,在我们4次调用TestAdd()函数的过程中,我们都是在调用内部的函数。这个时候,虽然外部函数已经运行结束了,但外部函数的变量a却被内部函数(闭包)引用,所以a并没有被销毁,而是被保存了起来,并且可以通过闭包继续操作。当然,外界无法访问a,它成了内部函数(闭包)的“私有变量”/

    也就是说 内部函数会close-over(遮蔽,封盖)外部函数的变量,直到内部函数全部调用完毕。

    这里特别要注意,你不能写成这样:

    var Testadd = function(){
    
       var a = 5;
       return function(){
    
          return a += 5;
        }
    };
    
    TestAdd();    // function(){return a += 5 ;}
    TestAdd();    // function(){return a += 5 ;}
    TestAdd();    // function(){return a += 5 ;}
    TestAdd();    // function(){return a += 5 ;}
  • 相关阅读:
    The commands of Disk
    How to build a NFS Service
    Apache的dbutils的架构图
    Spring使用ThreadLocal解决线程安全问题
    NIO流程
    Servlet 生命周期、工作原理
    forward和redirect的区别
    笔记:Java 性能优化权威指南 第9、10、11章 GlassFish、Web应用、Web Service、EJB性能调优
    几个关于Java内存泄露方面的面试题
    MAT 检测 Java内存泄露检测
  • 原文地址:https://www.cnblogs.com/wphl-27/p/10551025.html
Copyright © 2011-2022 走看看