关于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. JAMstack 最佳实践

    摘自官方介绍,没有翻译(没必要,已经比较简单了,重要的就是进行每条的诠释了,后续...) Entire Project on a CDN Because JAMstack projects don’t ...

  2. 客户端如何调用WebService并且POST数据

    直接上代码 using System; using System.Collections.Generic; using System.Linq; using System.Text;using Sys ...

  3. 洛谷 1365 WJMZBMR打osu! / Easy

    题目:https://www.luogu.org/problemnew/show/P1365 大水题.记录一下o的期望长度. 关键是(x+1)^2=x^2+2*x+1. #include<ios ...

  4. MyBatis缓存结构

    Mybatis Cache结构图: CacheKey(statementId, sql, sqlParams,other). 上图展示了Mybatis Cache的结构: 1)每个Mapper对应一块 ...

  5. MATLAB 02

    对一组数据作线性回归,并绘图 clear all; % 输入数据x和y x = [ ]'; y = [11 13 14 15 16 18 20 21 22 25 26 28 29 31]'; x = ...

  6. Apache CXF使用Jetty发布WebService

    一.概述 Apache CXF提供了用于方便地构建和开发WebService的可靠基础架构.它允许创建高性能和可扩展的服务,可以部署在Tomcat和基于Spring的轻量级容器中,也可以部署在更高级的 ...

  7. chrome浏览器,调试详解,调试js、调试php、调试ajax

    1.可以看到js报错 2.可以看到php报错 3.可以看到ajax返回的信息,以及报错情况 4.可以看到调用了那些内容以及顺序 5.可以调试js代码 6.可以查看session等等 功能非常之强大. ...

  8. java NIO(转载)

    (原文地址:https://zhuanlan.zhihu.com/p/23488863) NIO(Non-blocking I/O,在Java领域,也称为New I/O),是一种同步非阻塞的I/O模型 ...

  9. WP8.1通过StreamSocket连接C++服务器

    注:当服务端和手机模拟器运行在一台机器时,会有奇怪错误.将服务端放在其它机器上更改客户端连接地址,运行正常.或者直接用本机modern调试也可以. 实例化一个对象 StreamSocket clien ...

  10. leetcode378

    public class Solution { public int KthSmallest(int[,] matrix, int k) { ); ); var list = new List< ...