理解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语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
随机推荐
- [poj 1144]Network[Tarjan求割点]
题意: 求一个图的割点. 输入略特别: 先输入图中点的总数, 接下来每一行首先给出一个点u, 之后给出一系列与这个点相连的点(个数不定). 行数也不定, 用0作为终止. 这样的输入还是要保证以数字读入 ...
- UIPageViewController跳跃切换的问题
使用的是XHScrollMenu和UIPageViewController来构建5个页面: ViewController1, ViewController2, ViewController3, Vie ...
- 【DFS+小操作判重】【HDU2610+HDU2611】Sequence
题意 2610 按照长度优先 位置次之 输出所有不递减序列 2611 按照长度优先 大小次之 输出所有不递减序列 题解不写了 来源于http://www.cnblogs.com/wally/archi ...
- FormData实现文件上传实例
单提交,文件上传是一个常用又十分麻烦的功能,以前要上传文件通常都是借助插件或者flash来实现,噼里啪啦的加载一大堆东西.自从有了HTML5的FormData后,老板再也不用担心我的上传了. Form ...
- UVA 10305 Ordering Tasks
题意: 给出n和m,n代表总共有几个箱子.接下来m行,每行有a,b,表示b在a之后.输出一个合理的序列. 分析: 简单的拓扑排序: 代码: #include <iostream>#incl ...
- IIS应用程序池自动回收问题的有效解决办法
问题:Timer不能持续执行,如果长时间没有访问,就会被IIs自动回收.造成一些定时作业无法完成. 解决方式1:改用windows服务或是winform方式 解决方式2:在Application_En ...
- SQL————高级查询
高级查询 --连接查询 select * from 表1,表2 ————形成笛卡尔积 select * from 表1,表2 where 表1.主键=表2.外键 ————主外键位置可以互换 --jo ...
- 10Cookie
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...
- 整理mysql的一些常用用法
在php项目中,使用mysql的一些常用的语句,今天有空系统整体一下.有些整理自网络,如有错误,请指正,谢谢.... #显示数据库和显示数据表show databases;use databaseNa ...
- web app变革之rem(转载)
rem这是个低调的css单位,近一两年开始崭露头角,有许多同学对rem的评价不一,有的在尝试使用,有的在使用过程中遇到坑就弃用了.但是我对rem综合评价是用来做web app它绝对是最合适的人选之一. ...