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的简单&简陋Tabs插件代码
Feb 09 Javascript
用最通俗易懂的代码帮助新手理解javascript闭包 推荐
Mar 01 Javascript
经过绑定元素时会多次触发mouseover和mouseout事件
Feb 28 Javascript
Jquery中的$.each获取各种返回类型数据的使用方法
May 03 Javascript
简单谈谈原生js的math对象
Jun 27 Javascript
为什么我们要做三份 Webpack 配置文件
Sep 18 Javascript
详解自定义ajax支持跨域组件封装
Feb 08 Javascript
Vue项目安装插件并保存
Jan 28 Javascript
vue+Element实现搜索关键字高亮功能
May 28 Javascript
JavaScript 自定义html元素鼠标右键菜单功能
Dec 02 Javascript
JS控制下拉列表左右选择实例代码
May 08 Javascript
四十九个javascript小知识实用技巧
Nov 20 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中的unicode和utf8编码
2015/06/10 PHP
特殊字符、常规符号及其代码对照表
2006/06/26 Javascript
javascript 常用关键字列表集合
2007/12/04 Javascript
Javascript的数组与字典用法与遍历对象的属性技巧
2012/11/07 Javascript
jQuery侧边栏随窗口滚动实现方法
2013/03/04 Javascript
js函数与php函数的区别实例浅析
2015/01/12 Javascript
jquery插件jquery.LightBox.js实现点击放大图片并左右点击切换效果(附demo源码下载)
2016/02/25 Javascript
jquery判断对象是否为空并遍历对象的简单实例
2016/07/26 Javascript
浅析javascript中的Event事件
2016/12/09 Javascript
JS实现元素上下左右移动效果
2017/10/18 Javascript
基于input动态模糊查询的实现方法
2017/12/12 Javascript
微信小程序网络封装(简单高效)
2018/08/06 Javascript
在微信小程序中保存网络图片
2019/02/12 Javascript
微信小程序3种位置API的使用方法详解
2019/08/05 Javascript
vue 使用vant插件做tabs切换和无限加载功能的实现
2020/11/04 Javascript
nuxt 自定义 auth 中间件实现令牌的持久化操作
2020/11/05 Javascript
vue 防止页面加载时看到花括号的解决操作
2020/11/09 Javascript
[01:20]DOTA2更新全新英雄 天涯墨客现已加入游戏
2018/08/25 DOTA
python使用cStringIO实现临时内存文件访问的方法
2015/03/26 Python
使用Python的web.py框架实现类似Django的ORM查询的教程
2015/05/02 Python
Python中处理字符串的相关的len()方法的使用简介
2015/05/19 Python
使用Python实现BT种子和磁力链接的相互转换
2015/11/09 Python
Flask框架的学习指南之用户登录管理
2016/11/20 Python
python编写Logistic逻辑回归
2020/12/30 Python
python命名空间(namespace)简单介绍
2019/08/10 Python
TensorFlow学习之分布式的TensorFlow运行环境
2020/02/05 Python
python解释器安装教程的方法步骤
2020/07/02 Python
html5 input元素新特性_动力节点Java学院整理
2017/07/06 HTML / CSS
德国高品质男装及配饰商城:Cultizm(Raw Denim原色牛仔裤)
2018/04/16 全球购物
Nike加拿大官网:Nike.com (CA)
2019/04/09 全球购物
军训自我鉴定
2014/01/22 职场文书
2014年消防工作实施方案
2014/02/20 职场文书
小学班主任培训方案
2014/06/04 职场文书
小学工作总结2015
2015/05/04 职场文书
班干部学习委员竞选稿
2015/11/20 职场文书
使用python将HTML转换为PDF pdfkit包(wkhtmltopdf) 的使用方法
2022/04/21 Python