Javascript的闭包


Posted in Javascript onDecember 31, 2009

简介
Closure
所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
闭包是 ECMAScript (JavaScript)最强大的特性之一,但用好闭包的前提是必须理解闭包。闭包的创建相对容易,人们甚至会在不经意间创建闭包,但这些无意创建的闭包却存在潜在的危害,尤其是在比较常见的浏览器环境下。如果想要扬长避短地使用闭包这一特性,则必须了解它们的工作机制。而闭包工作机制的实现很大程度上有赖于标识符(或者说对象属性)解析过程中作用域的角色。

关于闭包,最简单的描述就是 ECMAScript 允许使用内部函数--即函数定义和函数表达式位于另一个函数的函数体内。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。也就是说,内部函数会在外部函数返回后被执行。而当这个内部函数执行时,它仍然必需访问其外部函数的局部变量、参数以及其他内部函数。这些局部变量、参数和函数声明(最初时)的值是外部函数返回时的值,但也会受到内部函数的影响。

遗憾的是,要适当地理解闭包就必须理解闭包背后运行的机制,以及许多相关的技术细节。虽然本文的前半部分并没有涉及 ECMA 262 规范指定的某些算法,但仍然有许多无法回避或简化的内容。对于个别熟悉对象属性名解析的人来说,可以跳过相关的内容,但是除非你对闭包也非常熟悉,否则最好是不要跳过下面几节。

对象属性名解析
ECMAScript 认可两类对象:原生(Native)对象和宿主(Host)对象,其中宿主对象包含一个被称为内置对象的原生对象的子类(ECMA 262 3rd Ed Section 4.3)。原生对象属于语言,而宿主对象由环境提供,比如说可能是文档对象、DOM 等类似的对象。

原生对象具有松散和动态的命名属性(对于某些实现的内置对象子类别而言,动态性是受限的--但这不是太大的问题)。对象的命名属性用于保存值,该值可以是指向另一个对象(Objects)的引用(在这个意义上说,函数也是对象),也可以是一些基本的数据类型,比如:String、Number、Boolean、Null 或 Undefined。其中比较特殊的是 Undefined 类型,因为可以给对象的属性指定一个 Undefined 类型的值,而不会删除对象的相应属性。而且,该属性只是保存着 undefined 值。

下面简要介绍一下如何设置和读取对象的属性值,并最大程度地体现相应的内部细节。

值的赋予
对象的命名属性可以通过为该命名属性赋值来创建,或重新赋值。即,对于:

var objectRef = new Object(); //创建一个普通的 javascript 对象。
可以通过下面语句来创建名为 “testNumber” 的属性:

objectRef.testNumber = 5;
/* - 或- */
objectRef["testNumber"] = 5;
在赋值之前,对象中没有“testNumber” 属性,但在赋值后,则创建一个属性。之后的任何赋值语句都不需要再创建这个属性,而只会重新设置它的值:

objectRef.testNumber = 8;
/* - 或- */
objectRef["testNumber"] = 8;
稍后我们会介绍,Javascript 对象都有原型(prototypes)属性,而这些原型本身也是对象,因而也可以带有命名的属性。但是,原型对象命名属性的作用并不体现在赋值阶段。同样,在将值赋给其命名属性时,如果对象没有该属性则会创建该命名属性,否则会重设该属性的值。

更详细的请查看下面的文章:
http://demo.3water.com/js/javascript_bibao/index.htm

Javascript 相关文章推荐
jquery 插件 web2.0分格的分页脚本,可用于ajax无刷新分页
Dec 25 Javascript
jquery中动态效果小结
Dec 16 Javascript
IE图片缓存document.execCommand("BackgroundImageCache",false,true)
Mar 01 Javascript
jquery修改网页背景颜色通过css方法实现
Jun 06 Javascript
讲解JavaScript中for...in语句的使用方法
Jun 03 Javascript
Bootstrap 模态框(Modal)插件代码解析
Dec 21 Javascript
parabola.js抛物线与加入购物车效果的示例代码
Oct 25 Javascript
如何使用 vue + d3 画一棵树
Dec 03 Javascript
你可能不知道的CORS跨域资源共享
Mar 13 Javascript
Weex开发之WEEX-EROS开发踩坑(小结)
Oct 16 Javascript
Vue v-model组件封装(类似弹窗组件)
Jan 08 Javascript
在vue中使用回调函数,this调用无效的解决
Aug 11 Javascript
javascript Onunload与Onbeforeunload使用小结
Dec 31 #Javascript
JavaScript 常用函数
Dec 30 #Javascript
jQuery的三种$()
Dec 30 #Javascript
jquery UI 1.72 之datepicker
Dec 29 #Javascript
用js做一个小游戏平台 (一)
Dec 29 #Javascript
js 学习笔记(三)
Dec 29 #Javascript
js DOM模型操作
Dec 28 #Javascript
You might like
Discuz 5.0 中读取纯真IP数据库函数分析
2007/03/16 PHP
php error_log 函数的使用
2009/04/13 PHP
做了CDN获取用户真实IP的函数代码(PHP与Asp设置方式)
2013/04/13 PHP
PHP图片处理之使用imagecopy函数添加图片水印实例
2014/11/19 PHP
php实现插入排序
2015/03/29 PHP
Docker搭建自己的PHP开发环境
2018/02/24 PHP
laravel 解决Eloquent ORM的save方法无法插入数据的问题
2019/10/21 PHP
js截取函数(indexOf,join等)
2010/09/01 Javascript
JavaScript高级程序设计阅读笔记(五) ECMAScript中的运算符(一)
2012/02/27 Javascript
JS保留两位小数 四舍五入函数的小例子
2013/11/20 Javascript
js类定义函数时用prototype与不用的区别示例介绍
2014/06/10 Javascript
深入理解JavaScript系列(45):代码复用模式(避免篇)详解
2015/03/04 Javascript
在Ubuntu系统上安装Node.JS的教程
2015/10/15 Javascript
Bootstrap在线电子商务网站实战项目5
2016/10/14 Javascript
Bootstrap3 模态框使用实例
2017/02/22 Javascript
Node.JS利用PhantomJs抓取网页入门教程
2017/05/19 Javascript
JS获取鼠标坐标并且根据鼠标位置不同弹出不同内容
2017/06/12 Javascript
jQuery模拟爆炸倒计时功能实例代码
2017/08/21 jQuery
vue中uni-app 实现小程序登录注册功能
2019/10/12 Javascript
实例分析JS中的相等性判断===、 ==和Object.is()
2019/11/17 Javascript
vue路由结构可设一层方便动态添加路由操作
2020/08/31 Javascript
antd多选下拉框一行展示的实现方式
2020/10/31 Javascript
[30:00]完美世界DOTA2联赛PWL S2 Rebirth vs LBZS 第二场 11.28
2020/12/01 DOTA
wxPython事件驱动实例详解
2014/09/28 Python
Python网页解析利器BeautifulSoup安装使用介绍
2015/03/17 Python
Python2随机数列生成器简单实例
2017/09/04 Python
浅谈python装饰器探究与参数的领取
2017/12/01 Python
微信跳一跳自动运行python脚本
2018/01/08 Python
Finishline官网:美国一家领先的运动品牌鞋类、服装零售商
2016/07/20 全球购物
servlet面试题
2012/08/20 面试题
送货司机岗位职责
2013/12/11 职场文书
《和田的维吾尔》教学反思
2014/04/14 职场文书
护理学专业求职信
2014/06/29 职场文书
求职自我评价范文100字
2014/09/23 职场文书
2014小学年度工作总结
2014/12/20 职场文书
redis 查看所有的key方式
2021/05/07 Redis