理解JS闭包
从事web开发工作,尤其主要是做服务器端开发的,难免会对客户端语言JavaScript一些概念有些似懂非懂的,甚至仅停留在实现功能的层面上,接下来的文章,是记录我对JavaScript的一些概念的理解。欢迎大牛拍砖吐糟
理解JS中的闭包,首先理解JavaScript中的作用域以及作用域链的问题,可以参考下我的拙见JS函数作用域及作用域链理解。
什么是闭包
学术说法:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。(你能看懂吗?反正我不能)
专业说法:函数对象可以通过作用域链相互关联起来,函数体内部的变量都可以保存在函数作用域内。(这个你懂吗?我略懂)
通俗说法:所有JavaScript函数都是闭包,因为函数都是对象,都关联到作用域,并且变量都保存在函数作用域内。(这个有点扯,困惑我的闭包,就这么简单)
但是我们通常说的闭包是当一个函数嵌套另一个函数,外部函数将嵌套函数对象作为返回值返回的时候,我们把这种情况称为闭包。
看下面一个例子
function func() {
var num = 0; //声明局部变量:num
function f() { //嵌套函数,在作用域里
console.log(++num)
}
return f(); //调用嵌套函数f,并将f的执行结果返回
}
func(); //输出:1
函数func()声明了一个局部变量,并定义了一个函数f(),最后将函数f()的执行结果返回。很容易理解输出结果为1。现在我们将这段代码稍作改动,如下面
function func() {
var num = 0; //声明局部变量:num
function f() { //嵌套函数,在作用域里
console.log(++num)
}
return f; //调用嵌套函数f,并将f的执行结果返回
}
var ff = func();
ff(); //输出:1
ff(); //输出:2
ff(); //输出:3
现在函数func()仅仅返回函数内嵌套的一个函数对象,而不是直接返回结果。在定义函数作用域外面调用嵌套函数,由于这个函数的作用域链是在函数定义的时候就已经创建的。嵌套的函数f()定义在这个作用域链里,并且变量num又是局部变量,不管在何时何地执行函数f(),这种绑定依然有效。因此,局部变量会一直保存下来。正式因为闭包的这一强大特性,才是其显得非常重要。
闭包实现
当一个函数func()创建后,它保存了一个作用域链,并且作用域链会被函数func()中的作用域中可访问的数据对象num填充。
执行此函数func()时会创建一个称为“运行期上下文(execution context)”的内部对象,运行期上下文定义了函数执行时的环境。并且运行期上下文对应自己的作用域链,同时它的作用域链初始化为当前运行函数func()的[[Scope]]所包含的对象。
然后执行环境会创建一个活动对象(call object),用来报讯局部变量,并把这个对象添加至作用域链[[Scope]]中。假如不存在嵌套函数,也没有其他引用的时候,活动对象就会被当做垃圾回收掉。但是这里有嵌套函数f(),并将函数f()作为返回值返回时,就会又一个外部引用指向这个嵌套函数f(),活动对象就不会当做垃圾回收掉,并且活动对象指向的变量所绑定的对象也不会被回收。
理解JS闭包的更多相关文章
- javascript深入理解js闭包(转)
javascript深入理解js闭包 转载 2010-07-03 作者: 我要评论 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. ...
- 理解JS闭包的几个小实验
学了JavaScript有一段时间了,但是对闭包还是不太理解,于是怀着心中的疑问做了几个小实验,终于有点明白了. 首先看一下MDN上的定义:闭包是函数和声明该函数的词法环境的组合. 简单来说,闭包是一 ...
- javascript深入理解js闭包
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
- 深入理解JS闭包
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
- 通俗易懂的深入理解js闭包
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域 ...
- 理解js闭包(二)
@(编程) 一.什么是闭包? 官方"的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. 相信很少有人能直接看懂这句话,因为他 ...
- javascript深入理解js闭包[转]
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
- (转)javascript深入理解js闭包
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
- javascript深入理解js闭包(个人理解,大神勿喷)
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
随机推荐
- hdu 2059 龟兔赛跑(dp)
龟兔赛跑 Problem Description 据说在很久很久以前,可怜的兔子经历了人生中最大的打击——赛跑输给乌龟后,心中郁闷,发誓要报仇雪恨,于是躲进了杭州下沙某农业园卧薪尝胆潜心修炼,终于练成 ...
- Dollar Dayz(大数母函数,高低位存取)
Dollar Dayz Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5655 Accepted: 2125 Descr ...
- IE下全局对象报 脚本错误提示“对象不支持此属性或方法”解决方案
原来是IE会把页面中的元素id可以直接当变量名一样使用,但是这个id变量不能被赋值. 例如: <body id='body'> <script type="text/jav ...
- HTML 4.01 符号实体
HTML 4.01 符号实体 http://www.w3school.com.cn/tags/html_ref_symbols.html
- UVA 1622 Robot
题意: 给出n*m个格子,每个格子里有一个机器人,可以执行东南西北四种指令,但是移动出格就会爆炸.给出四种指令的个数,求最多完成多少次指令. 分析: 首先对输入数据进行处理,使得cw≥ce.cn≥cs ...
- Android学习之菜单
android中包含多种菜单,本例带来的是选项菜单和上下文菜单. 1.选项菜单 在android中,开发者可以在xml文档中部署所要添加的菜单,在后台调用即可. <menu xmlns:andr ...
- Silverlight学习笔记之页面跳转
在进行项目开发的时候,经常遇到页面之间的跳转,包括silverlight之间以及silverlight和html之间的跳转. silverlight之间的页面跳转包含两点: 1.主窗体和子窗体 用户新 ...
- 解决水晶报表在IIS7下的权限问题。
http://52live.blog.sohu.com/69025059.html 解决水晶报表在IIS7下的权限问题. 有些事情真是“踏破铁鞋无觅处,得来全不费功夫”!困扰了我一段时间的水晶报表在I ...
- Blend制作TextButton和ImageButton
最近看了几个高人做的软件界面(http://kaodigua.net/),羡慕嫉妒到不行,决定学习一下Blend的用法,马上觉得WPF开发的界面设计就应该放在Blend里面做.学习了两位大神的博客(h ...
- 5.7 cm server-agent 会出现无法启动
异常信息如下: 离线安装cloudera-scm-agent5.7的Unable to create the pidfile问题 在离线安装Cloudera Manager启动agent出现了如下异常 ...