关于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 ;}

再谈JavaScript的closure--JavaScript 闭包的更多相关文章

  1. 再谈javascript面向对象编程

    前言:虽有陈皓<Javascript 面向对象编程>珠玉在前,但是我还是忍不住再画蛇添足的补上一篇文章,主要是因为javascript这门语言魅力.另外这篇文章是一篇入门文章,我也是才开始 ...

  2. JavaScript 运行机制详解:再谈Event Loop

    原文地址:http://www.ruanyifeng.com/blog/2014/10/event-loop.html 一年前,我写了一篇<什么是 Event Loop?>,谈了我对Eve ...

  3. javascript运行机制详解: 再谈Event Loop(转)

    作者: 阮一峰 日期: 2014年10月 8日 一年前,我写了一篇<什么是 Event Loop?>,谈了我对Event Loop的理解. 上个月,我偶然看到了Philip Roberts ...

  4. 【repost】JavaScript 运行机制详解:再谈Event Loop

    一年前,我写了一篇<什么是 Event Loop?>,谈了我对Event Loop的理解. 上个月,我偶然看到了Philip Roberts的演讲<Help, I'm stuck i ...

  5. [转载]JavaScript 运行机制详解:再谈Event Loop

    https://app.yinxiang.com/shard/s8/sh/b72fe246-a89d-434b-85f0-a36420849b84/59bad790bdcf6b0a66b8b93d5e ...

  6. 【朴灵评注】JavaScript 运行机制详解:再谈Event Loop

    PS: 我先旁观下大师们的讨论,得多看书了~   别人说的:“看了一下不觉得评注对到哪里去,只有吹毛求疵之感. 比如同步异步介绍,本来就无大错:比如node图里面的OS operation,推敲一下就 ...

  7. 再谈JavaScript的数据类型问题

    JavaScript的数据类型问题已经讨论过很多次了,但许多人还有许多书仍然沿用着错误的.混乱的一些观点,所以就再细讲一回. 提及这个讨论的原因在于argb同学在我的MSN博客上的一段回复,又更早的起 ...

  8. [转] JavaScript 运行机制详解:再谈Event Loop

    一.为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊. Java ...

  9. javascript深入理解js闭包

    一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...

随机推荐

  1. matlab中求逆矩阵的高斯消元法实现的代码

    function qiuni =INV_GET(a)N=length(a);M=eye(N);%得到上三角矩?for i=1:N max=a(i,i); A=i; for j=i+1:N if(abs ...

  2. Oracle的闪回特性之恢复truncate删除表的数据

    Oracle的闪回特性之恢复truncate删除表的数据 SQL> show parameter flashback NAME                                 T ...

  3. Oracle中exp,imp(导入导出)数据迁移注意事项

    这几天做开发库schema备份,出现些问题,记录一下.一,exp时,os语言环境和数据库不同时会自动发生转换.   如果操作系统的字符集小于数据库字符集,就可能出现乱码现象.imp时,同理,也是有可能 ...

  4. FastAdmin 出现慢的问题 (DB host)

    FastAdmin 出现慢的问题 用户反馈断网后 FastAdmin 后台变慢. 而且是很多同事出现一样的现象. 查看了 runtime / log 里的日志,发现 DB 时间超过 20s. 经过群里 ...

  5. Linux cc与gcc

    三个源文件:main.c sum.c show.c /* main.c */ extern int sum(int m, int n); extern void show(int data); int ...

  6. 根据wsdl文件生成WebService客户端代码

    有时候在项目中,一个项目可能有好几个公司在做.系统之间难免会出现互相调用接口的现象,这时候有一种办法就是使用webService.本篇文章将介绍如何将对接系统提供的WebService接口,根据对方提 ...

  7. nginx.conf自己整理的中文解读

    自己收集了网上有关conf文件的中文详解,这样以后就不怕看不懂nginx的配置文件啦! #定义Nginx运行的用户和用户组user www www; #nginx进程数,建议设置为等于CPU总核心数. ...

  8. MongoDB高级查询用法大全 (转)

    http://www.cnblogs.com/t2xingzhe/p/3555268.html

  9. 三级联动第二种方法 三级联动数据.js

    var data = { '0':{2:'北京',25:'天津',24:'上海',31:'重庆',130000:'河北省',140000:'山西省',150000:'内蒙古自治区',210000:'辽 ...

  10. 如何将serialport接收的字符串转换成十六进制数c#

    关注 baihe_591 baihe_591 本版等级:   #1 得分:0回复于: 2008-06-02 09:44:00 Byte[] byte=new Byte[1];byte=0xf1;por ...