原型、作用域、闭包的完整解释---大漠穷秋[译].docVIP

原型、作用域、闭包的完整解释---大漠穷秋[译].doc

  1. 1、本文档共19页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
原型、作用域、闭包的完整解释---大漠穷秋[译].doc

原文:Richard Cornford. March 2004. 翻译:大漠穷秋 2010-11-23 脚本娃娃团队出品 介绍 闭包 闭包是一个表达式(通常是一个函数),可以有任意参数,连同绑定这些参数的环境(它“封闭”了表达式)一起构成。 闭包是ECMAScript (javascript)最强大的特性之一,但是不理解就无法正确地利用它。然而,创建它们相对容易,甚至无意间就可以创建,创建它们会在造成潜在的有害后果,尤其在一些相对通用的浏览器环境中。为了避免无意间遭遇这些弊端,并利用它们提供的便利,非常有必要理解其机制。这在很大成程度上取决于标识符解析过程中作用域链所扮演的角色,以及对象属性名解析方面的协议。 闭包的简单解释是,ECMAScript支持内部函数,函数定义和函数表达式位于其它函数体内部。这样就允许这些内部函数访问所有局部变量、(外部)函数的参数和外部函数中声明的(其它)内部函数。当这些内部函数之一可以在其所属的(外部)函数之外被访问时,就形成了一个闭包。这样,在外部函数返回之后它仍然可以执行。这时它仍然可以访问局部变量、参数和外部函数中声明的其它内部函数。当外部函数返回之后,这些局部变量、(外部)函数参数和函数定义(最初)仍然持有它们拥有的值,并且可以与内部函数交互。 不幸的是,正确理解闭包需要理解它们背后的机制,以及相当多的技术细节。虽然在以下描述的开头部分,ECMA 262指定的一些算法已经被废弃了,但是很多不能省略或者简单解释。熟悉对象属性名解析的个人可以跳过以下小节,并且可以停止阅读此文档然后回去运用它们。 对象属性名决议 CMAScript承认两种类型的对象,“本地对象”和“宿主对象”(Native Object and Host Object)以及一个本地对象的子集,叫做“内置对象”(Built-in Object)(ECMA262第三版4.3节)。本地对象属于语言,宿主对象由环境提供,例如可以是document对象、DOM节点等等。 本地对象是松散的,并且是命名属性的动态包(当涉及到内置对象的子集时,一些实现不是那么动态,但是这通常无关紧要)。对象定义的命名属性将会持有一个值,它可以是到另一个对象的引用(从这个意义上说函数也是对象),或者是一个原始值: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对象的属性自身也可以是对象,稍后详述,并且原型(prototype)也可以拥有命名属性。但是它在赋值的时候不起作用。如果赋值的时候,实际的对象没有相应名称的属性,一个拥有此名称的属性将会被创建,并且把值赋给它。如果它已经拥有此属性则重新赋值。 读取值 从对象属性上读取值时原型开始起作用。如果一个对象拥有一个属性,与属性访问器(译者注,指的就是属性访问操作符)的属性名相同,则返回这个属性的值: /* 给一个命名属性赋值 如果在赋值之前对象没有一个对应名称的属性 在赋值之后我们会获得一个 */ objectRef.testNumber = 8; /* 从属性上读回这个值*/ var val = objectRef.testNumber; /* 然后,val现在持有了个值为8,就是我们刚才赋给对象命名属性的值。*/ 但是所有对象都可以有原型,并且原型也是对象,所以接着它们也可以有原型,原型又可以有原型,如此就形成了所谓的原型链。当链条中的对象有一个值为null的原型时,原型链终止。Object构造器的默认原型值为null,所以: var objectRef = new Object(); //创建一个通用的J

文档评论(0)

aiwendang + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档