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 相关文章推荐
激活 ActiveX 控件
Oct 09 Javascript
JS实现self的resend
Jul 22 Javascript
面向对象的Javascript之三(封装和信息隐藏)
Jan 27 Javascript
js关于字符长度限制的问题示例探讨
Jan 24 Javascript
jquery 获取 outerHtml 包含当前节点本身的代码
Oct 30 Javascript
探究Vue.js 2.0新增的虚拟DOM
Oct 20 Javascript
js实现不提示直接关闭网页窗口
Mar 30 Javascript
Vue.js render方法使用详解
Apr 05 Javascript
设置cookie指定时间失效(实例代码)
May 28 Javascript
react-native DatePicker日期选择组件的实现代码
Sep 12 Javascript
详解如何使用koa实现socket.io官网的例子
Nov 04 Javascript
使用form-create动态生成vue自定义组件和嵌套表单组件
Jan 18 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
发布一个用PHP fsockopen写的HTTP下载的类
2007/02/22 PHP
那些年一起学习的PHP(一)
2012/03/21 PHP
PHP实现的汉字拼音转换和公历农历转换类及使用示例
2014/07/01 PHP
分享一则PHP定义函数代码
2015/02/26 PHP
PHP 使用 Imagick 裁切/生成缩略图/添加水印自动检测和处理 GIF
2016/02/19 PHP
Yii框架组件和事件行为管理详解
2016/05/20 PHP
PHP上传Excel文件导入数据到MySQL数据库示例
2016/10/25 PHP
PHP 超级全局变量相关总结
2020/06/30 PHP
Jsonp 跨域的原理以及Jquery的解决方案
2010/05/18 Javascript
jQuery选择没有colspan属性的td的代码
2010/07/06 Javascript
javascript工具库代码
2012/03/29 Javascript
artDialog 4.1.5 Dreamweaver代码提示/补全插件 附下载
2012/07/31 Javascript
JavaScript自定义日期格式化函数详细解析
2014/01/14 Javascript
jQuery.extend()、jQuery.fn.extend()扩展方法示例详解
2014/05/08 Javascript
Javascript 拖拽雏形中的一些问题(逐行分析代码,让你轻松了拖拽的原理)
2015/01/23 Javascript
javascript事件模型实例分析
2015/01/30 Javascript
使用jQuery在移动页面上添加按钮和给按钮添加图标
2015/12/04 Javascript
AngularJS实现树形结构(ztree)菜单示例代码
2016/09/18 Javascript
详解Vue中使用v-for语句抛出错误的解决方案
2017/05/04 Javascript
微信小程序实现横向增长表格的方法
2018/07/24 Javascript
vue 开发之路由配置方法详解
2019/12/02 Javascript
基于vue的tab-list类目切换商品列表组件的示例代码
2020/02/14 Javascript
基于element-ui封装表单金额输入框的方法示例
2021/01/06 Javascript
Python 拷贝对象(深拷贝deepcopy与浅拷贝copy)
2008/09/06 Python
Python实现抓取页面上链接的简单爬虫分享
2015/01/21 Python
神经网络理论基础及Python实现详解
2017/12/15 Python
Pytorch十九种损失函数的使用详解
2020/04/29 Python
YOOX美国官方网站:全球著名的多品牌时尚网络概念店
2016/09/11 全球购物
Gucci法国官方网站:意大利奢侈品牌
2018/07/25 全球购物
安全的后院和健身蹦床:JumpSport
2019/07/15 全球购物
英国家具、照明、家居用品网上商店:Wayfair.co.uk
2020/02/13 全球购物
信息管理专业学生自荐信格式
2013/09/22 职场文书
给老婆大人的检讨书
2014/02/24 职场文书
小学班级口号
2014/06/09 职场文书
小区保洁员岗位职责
2015/04/10 职场文书
90后经典动画片排行:《数码宝贝》第二,《小鲤鱼历险记》在榜
2022/03/18 日漫