理解 Javascript 的闭包
2015-06-28 11:01
776 查看
http://www.oschina.net/question/28_41112
前言:还是一篇入门文章。Javascript中有几个非常重要的语言特性——对象、原型继承、闭包。其中闭包 对于那些使用传统静态语言C/C++的程序员来说是一个新的语言特性。本文将以例子入手来介绍Javascript闭包的语言特性,并结合一点 ECMAScript语言规范来使读者可以更深入的理解闭包。注:本文是入门文章,例子素材整理于网络,如果你是高手,欢迎针对文章提出技术性建议和意见。本文讨论的是Javascript,不想做语言对比,如果您对Javascript天生不适,请自行绕道。
什么是闭包
闭包是什么?闭包是Closure,这是静态语言所不具有的一个新特性。但是闭包也不是什么复杂到不可理解的东西,简而言之,闭包就是:闭包就是函数的局部变量集合,只是这些局部变量在函数返回后会继续存在。
闭包就是就是函数的“堆栈”在函数返回后并不释放,我们也可以理解为这些函数堆栈并不在栈上分配而是在堆上分配
当在一个函数内定义另外一个函数就会产生闭包
上面的第二定义是第一个补充说明,抽取第一个定义的主谓宾——闭包是函数的‘局部变量’集合。只是这个局部变量是可以在函数返回后被访问。(这个不是官方定义,但是这个定义应该更有利于你理解闭包)
做为局部变量都可以被函数内的代码访问,这个和静态语言是没有差别。闭包的差别在于局部变变量可以在函数执行结束后仍然被函数外的代码访问。这意味 着函数必须返回一个指向闭包的“引用”,或将这个”引用”赋值给某个外部变量,才能保证闭包中局部变量被外部代码访问。当然包含这个引用的实体应该是一个 对象,因为在Javascript中除了基本类型剩下的就都是对象了。可惜的是,ECMAScript并没有提供相关的成员和方法来访问闭包中的局部变 量。但是在ECMAScript中,函数对象中定义的内部函数()
inner function是可以直接访问外部函数的局部变量,通过这种机制,我们就可以以如下的方式完成对闭包的访问了。
?
好了,这个就是传说中闭包的效果,闭包在Javascript中有多种应用场景和模式,比如Singleton,Power Constructor等这些Javascript模式都离不开对闭包的使用。
ECMAScript闭包模型
ECMAScript到底是如何实现闭包的呢?想深入了解的亲们可以获取ECMAScript 规范进行研究,我这里也只做一个简单的讲解,内容也是来自于网络。在ECMAscript的脚本的函数运行时,每个函数关联都有一个执行上下文场景(Execution Context) ,这个执行上下文场景中包含三个部分
文法环境(The LexicalEnvironment)
变量环境(The VariableEnvironment)
this绑定
其中第三点this绑定与闭包无关,不在本文中讨论。文法环境中用于解析函数执行过程使用到的变量标识符。我们可以将文法环境想象成一个对象,该对 象包含了两个重要组件,环境记录(Enviroment Recode),和外部引用(指针)。环境记录包含包含了函数内部声明的局部变量和参数变量,外部引用指向了外部函数对象的上下文执行场景。全局的上下文 场景中此引用值为NULL。这样的数据结构就构成了一个单向的链表,每个引用都指向外层的上下文场景。
例如上面我们例子的闭包模型应该是这样,sayHello函数在最下层,上层是函数greeting,最外层是全局场景。如下图:
因此当sayHello被调用的时候,sayHello会通过上下文场景找到局部变量text的值,因此在屏幕的对话框中显示出”Hello Closure”
变量环境(The VariableEnvironment)和文法环境的作用基本相似,具体的区别请参看ECMAScript的规范文档。
闭包的样列
前面的我大致了解了Javascript闭包是什么,闭包在Javascript是怎么实现的。下面我们通过针对一些例子来帮助大家更加深入的理解闭包,下面共有5个样例,例子来自于JavaScriptClosures For Dummies(镜像)。
例子1:闭包中局部变量是引用而非拷贝
?
例子2:多个函数绑定同一个闭包,因为他们定义在同一个函数内。
?
?
例子4:外部函数所有局部变量都在闭包内,即使这个变量声明在内部函数定义之后。
?
例子5:每次函数调用的时候创建一个新的闭包
?
闭包的应用
Singleton 单件:?
参考:
JavaScript Closures For Dummies(镜像) 可惜都被墙了。Advance Javascript (Douglas Crockford 大神的视频,一定要看啊)
转载自 http://coolshell.cn/articles/6731.html
相关文章推荐
- 那些逐步掌握的JavaScript('arguments')
- Jsp:param标签的使用
- Extjs布局
- javascript中遇到的字符串对象处理
- js类型判断的方法
- Js学习文件上传
- 最简单的处理MVC中默认的Json方法返回时间的问题
- 100多个基础常用JS函数和语法集合大全
- 【HM】第3课:JavaScript高级
- JS的碰撞周期移动
- JSON处理
- 在JSP前台和后台传递参数乱码汇总
- 11. Firefox如何调试js脚本:
- Array的队列方法&重排序方法—— JS学习笔记2015-6-27(第68天)
- js 函数的参数 问题 arguments对象 及闭包
- JavaScript语法 (顺序+判断+选择+循环+其他=五种语句)演示
- Web 开发的 JavaScript 框架资料收集(15款)
- 谈谈Ext JS的组件——布局的使用方法续二
- 谈谈Ext JS的组件――布局的使用方法续二
- 谈谈Ext JS的组件——布局的使用方法续二