再谈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 ;}

 

posted on 2019-03-18 11:09  新西兰程序员  阅读(223)  评论(0编辑  收藏  举报