关于JavaScript的闭包,在个人博客上以前有一篇文章 https://www.cnblogs.com/wphl-27/p/8491327.htmlhtml
今天看了几篇文章,感受又有了一些更深的理解,特记录以下:闭包
其实关于JavaScript的闭包closure, 简单点理解能够以下:函数
在JavaScript中,一个函数A内部又包含一个函数B, 同时把内部函数B做为函数A的返回值,这个时候,就造成了一个闭包。
咱们来看一个简单的例子:spa
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上累加5code
咱们的需求是: 若是须要更改a的值,则只能经过TestAdd这个方法来更改,不能经过其余途径来更改htm
可是,咱们看看上面的代码,实现了咱们的需求吗? 咱们确实能够经过TestAdd方法来更改a的值,但同时因为a是一个全局变量,咱们在其余地方能够很容易的修改它的值,好比 a = 34; 因此,这个代码是达不到咱们需求的blog
如今咱们对它进行修改,咱们会很容易想到,既然需求是只能经过方法TestAdd来修改a的值,那么咱们能够把变量a放到TestAdd内部去,代码以下ip
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 闭包, 代码以下io
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 ;}