欢迎来到天天文库
浏览记录
ID:1536323
大小:98.00 KB
页数:18页
时间:2017-11-12
《原型、作用域、闭包的完整解释---大漠穷秋[译]》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库。
1、原文:RichardCornford.March2004.翻译:大漠穷秋2010-11-23脚本娃娃团队出品介绍闭包闭包是一个表达式(通常是一个函数),可以有任意参数,连同绑定这些参数的环境(它“封闭”了表达式)一起构成。闭包是ECMAScript(javascript)最强大的特性之一,但是不理解就无法正确地利用它。然而,创建它们相对容易,甚至无意间就可以创建,创建它们会在造成潜在的有害后果,尤其在一些相对通用的浏览器环境中。为了避免无意间遭遇这些弊端,并利用它们提供的便利,非常有必要理解其机制
2、。这在很大成程度上取决于标识符解析过程中作用域链所扮演的角色,以及对象属性名解析方面的协议。闭包的简单解释是,ECMAScript支持内部函数,函数定义和函数表达式位于其它函数体内部。这样就允许这些内部函数访问所有局部变量、(外部)函数的参数和外部函数中声明的(其它)内部函数。当这些内部函数之一可以在其所属的(外部)函数之外被访问时,就形成了一个闭包。这样,在外部函数返回之后它仍然可以执行。这时它仍然可以访问局部变量、参数和外部函数中声明的其它内部函数。当外部函数返回之后,这些局部变量、(外部)函
3、数参数和函数定义(最初)仍然持有它们拥有的值,并且可以与内部函数交互。不幸的是,正确理解闭包需要理解它们背后的机制,以及相当多的技术细节。虽然在以下描述的开头部分,ECMA262指定的一些算法已经被废弃了,但是很多不能省略或者简单解释。熟悉对象属性名解析的个人可以跳过以下小节,并且可以停止阅读此文档然后回去运用它们。对象属性名决议CMAScript承认两种类型的对象,“本地对象”和“宿主对象”("NativeObject"and"HostObject")以及一个本地对象的子集,叫做“内置对象”("
4、Built-inObject")(ECMA262第三版4.3节)。本地对象属于语言,宿主对象由环境提供,例如可以是document对象、DOM节点等等。本地对象是松散的,并且是命名属性的动态包(当涉及到内置对象的子集时,一些实现不是那么动态,但是这通常无关紧要)。对象定义的命名属性将会持有一个值,它可以是到另一个对象的引用(从这个意义上说函数也是对象),或者是一个原始值:String,Number,Boolean,Null或者Undefined。原生类型Undefined有点奇怪,利用它可以把一个
5、对象的属性赋值为Undefined,但是这么做不会从对象上删除这个属性;它保持为一个已定义的命名属性,仅仅持有了一个为undefined的值。以下是一个简单描述,属性值是如何在对象上设置和读取的,尽可能最大限度地省略内部细节。18赋值通过给这个命名属性指定一个值,可以创建对象的命名属性,或者为已存在的命名属性赋值。例如给定:varobjectRef=newObject();//创建一个普通的javascript对象。一个名为"testNumber"的属性可以这样创建:objectRef.testN
6、umber=5;/*或者*/objectRef["testNumber"]=5;在赋值之前,对象没有"testNumber"属性,但是在赋值之后会创建一个。所有后续赋值都没有必要创建属性,仅仅重新设置它的值:objectRef.testNumber=8;/*或者*/objectRef["testNumber"]=8;Javascript对象的属性自身也可以是对象,稍后详述,并且原型(prototype)也可以拥有命名属性。但是它在赋值的时候不起作用。如果赋值的时候,实际的对象没有相应名称的属性,一
7、个拥有此名称的属性将会被创建,并且把值赋给它。如果它已经拥有此属性则重新赋值。读取值从对象属性上读取值时原型开始起作用。如果一个对象拥有一个属性,与属性访问器(译者注,指的就是属性访问操作符)的属性名相同,则返回这个属性的值:/*给一个命名属性赋值如果在赋值之前对象没有一个对应名称的属性在赋值之后我们会获得一个*/objectRef.testNumber=8;/*从属性上读回这个值*/varval=objectRef.testNumber;/*然后,val现在持有了个值为8,就是我们刚才赋给对象命
8、名属性的值。*/但是所有对象都可以有原型,并且原型也是对象,所以接着它们也可以有原型,原型又可以有原型,如此就形成了所谓的原型链。当链条中的对象有一个值为null的原型时,原型链终止。Object构造器的默认原型值为null,所以:varobjectRef=newObject();//创建一个通用的JavaScript对象。创建一个对象的原型为Object.prototype,这个原型自身的属性为null。所以objectRef的原型链仅仅包含一个对象:Object.prototy
此文档下载收益归作者所有