关于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. winSCP连接FTP没有上传的权限

    错误: 原因: ftp用户为 1)查看ubantu中FTP文件夹目录所有者及权限,发现ftpName用户对FTP文件夹的权限为 “r-x”  ,仅有读,执行权限 2) chmod o=rwx ftp ...

  2. WinForm Flicker闪屏解决方案

    开发WinForm 程序时经常会遇到闪屏的问题,这会给用户造成很差的使用体验,所以必须妥善解决好这个问题. 首先,我们先要找出闪屏的原因,就我目前遇到的问题而言,其原因真是五花八门. 主要的原因有:使 ...

  3. Go基本语句

    递增递减语句 在GO中,++与--是作为语句而并不是作为表达式 package main import "fmt" func main() { a:= //a=a++ //语句而非 ...

  4. 【转】Jmeter常见问题

    说明:这些问答是从网上转载的,自己修改了其中的一些内容,如果大家兴趣,可以将大家在使用Jmeter的时候碰到的问题写下来,我们一起补充到这个问答里面,共同努力完善jmeter的资料. 1.  JMet ...

  5. linux composer的使用

    安装好的composer使用很简单,分两步加载组件例1.搜索组件:composer search phpexcel2.下载组件:composer require 厂商名/包名然后在使用该插件的脚本中引 ...

  6. Python print format() 格式化内置函数

    Python2.6 开始,新增了一种格式化字符串的函数 str.format(),它增强了字符串格式化的功能. 基本语法是通过 {} 和 : 来代替以前的 % . format 函数可以接受不限个参数 ...

  7. thinkphp中的多字段模糊匹配

    引言:有时候查询要匹配多个字段.比如查询地址,地址是由多个字段组成的.有省.市.区等等,以及详细地址.这个时候如何查询呢? 实现不同字段相同的查询条件 $User = M("User&quo ...

  8. a标签的四个伪类是什么?如何排序?为什么?

    爱恨分明原则: l v h a 注释:为了产生预期的效果,在 CSS 定义中,a:hover 必须位于 a:link 和 a:visited 之后 ! 注释:为了产生预期的效果,在 CSS 定义中,a ...

  9. Python实现SSH连接远程服务器

    首先需要安装paramiko模块 #-*- coding:utf-8 -*- __author__ = "MuT6 Sch01aR" import paramiko ssh = p ...

  10. 基本的Ceph性能测试工具和方法

    测试环境 1. 测试准备 1.1 磁盘读写性能 1.1.1 单个 OSD 磁盘写性能,大概 165MB/s. root@ceph1:~# echo 3 > /proc/sys/vm/drop_c ...