全面理解闭包机制.docVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
下面小编就为大家带来一篇全面理解闭包机制。 小编觉得挺不错的,现在就分享给大家, 也给大家做个参考。 var foo = Hello; var c =(function a() { fun ctio n b(){ var bar = World; alert(foo + bar); return bar; } return b; })()(); alert(foo + c); 本实例弹出两次 hello world ; 一、 什么是闭包? “官方”的解释是:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境 的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。 相信很少有人能直接看懂这句话,因为他描述的太学术。我想用如何在 Javascript中创 建一个闭包来告诉你什么是闭包, 因为跳过闭包的创建过程直接理解闭包的定义是非常困难 的。看下面这段代码: fun ctio n a(){ var i=0; fun ctio n b(){ alert(++i); } return b; } var c = a(); c(); 这段代码有两个特点: 1、 函数b嵌套在函数a内部; 2、 函数a返回函数b。 这样在执行完var c=a()后,变量c实际上是指向了函数 b,再执行c()后就会弹出一个窗 口显示i的值(第一次为1)。这段代码其实就创建了一个闭包,为什么?因为函数 a外的变 量c引用了函数a内的函数b,就是说: 当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。 我猜想你一定还是不理解闭包,因为你不知道闭包有什么作用,下面让我们继续探索。 二、 闭包有什么作用? 简而言之,闭包的作用就是在 a执行完并返回后,闭包使得 Javascript的垃圾回收机制 GC不会收回a所占用的资源,因为 a的内部函数b的执行需要依赖 a中的变量。这是对闭 包作用的非常直白的描述, 不专业也不严谨,但大概意思就是这样, 理解闭包需要循序渐进 的过程。 在上面的例子中,由于闭包的存在使得函数 a返回后,a中的i始终存在,这样每次执 行c(), i都是自加1后alert出i的值。 那 么我们来想象另一种情况,如果 a返回的不是函数 b,情况就完全不同了。因为 a 执行完后,b没有被返回给a的外界,只是被 a所引用,而此时 a也只会被b引 用,因此 函数a和b互相引用但又不被外界打扰 (被外界引用),函数a和b就会被GC回收。(关于 Javascript的垃圾回收机制将在后面详细介绍 ) 三、 闭包内的微观世界 女口果要更加深入的了解闭包以及函数 a和嵌套函数b的关系,我们需要引入另外几个 概念:函数的执行环境 (excution context)、活动对象(call object)、作用域(scope卜作用域链 (scope chain)。以函数a从定义到执行的过程为例阐述这几个概念。 1、 当定义函数a的时候,js解释器会将函数 a的作用域链(scope chain)设置为定义a时 a所在的环境”,如果a是一个全局函数,则 scope chain中只有window对象。 2、 当函数a执行的时候,a会进入相应的执行环境 (excution con text)。 3、 在创建执行环境的过程中,首先会为 a添加一个scope属性,即a的作用域,其值 就为第1步中的scope chain。即卩a.scope=a的作用域链。 4、 然后执行环境会创建一个活动对象 (call object)。活动对象也是一个拥有属性的对象, 但它不具有原型而且不能通过 JavaScript代码直接访问。创建完活动对象后,把活动对象添 加到a的作用域链的最顶端。此时 a的作用域链包含了两个对象: a的活动对象和 window 对象。 5、 下一步是在活动对象上添加一个 arguments属性,它保存着调用函数 a时所传递的 参数。 6、 最后把所有函数 a的形参和内部的函数 b的引用也添加到 a的活动对象上。在这一 步中,完成了函数b的的定义,因此如同第3步,函数b的作用域链被设置为 b所被定义的 环境,即a的作用域。 到此,整个函数a从定义到执行的步骤就完成了。此时 a返回函数b的引用给c,又函 数b的作用域链包含了对函数 a的活动对象的引用,也就是说b可以访问到a中定义的所有 变量和函数。函数b被c引用,函数b又依赖函数a,因此函数a在返回后不会被 GC回收。 当函数b执行的时候亦会像以上步骤一样。 因此,执行时b的作用域链包含了 3个对象: b的活动对象、a的活动对象和 window对象,如下图所示: 如图所示,当在函数b中访问一个变量的时候, 搜索顺序是先搜索自身的活动对象, 如 果存在则返回,如果不存在将继续搜索函数 a的活动

文档评论(0)

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

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

1亿VIP精品文档

相关文档