码迷,mamicode.com
首页 > Web开发 > 详细

学习JS闭包

时间:2015-06-12 11:29:21      阅读:135      评论:0      收藏:0      [点我收藏+]

标签:

闭包是什么?

  • MDN:闭包是指函数有自由独立的变量。换句话说,定义在闭包中的函数可以“记忆”它创建时候的环境。
  • JS高级程序设计:闭包是指有权访问另一个函数作用域中的变量的函数。

综合各种资料之后,我对闭包的理解是:

  • 闭包由函数和与其相关的引用环境组合而成;
  • 闭包允许函数访问其引用环境中的变量(又称自由变量);

下面是一个关于闭包的例子:

技术分享

通常,函数中的局部变量仅在函数的执行期间可用。一旦foo() 执行过后,我们会很合理的认为 name 变量将不再可用。

但实际并不是这样的。在上面的例子中,myName函数变成了一个闭包。

闭包是一种特殊的对象。它由两部分构成:函数,以及创建该函数的环境。环境由闭包创建时在作用域中的任何局部变量组成。因此,myName由ShowName 函数和闭包创建时作用域中存在的变量name组成。

 

下面是一个摘自MDN上一个关于闭包的例子。

技术分享

这里应该要注意的是,add5 和 add10 都是闭包。它们共享相同的函数定义,但是保存了不同的环境。在 add5 的环境中,x为 5。而在 add10 中,x 则为 10。

也就是说,每调用一次makeAdder(),都会创建一个新的环境,所以add5和add10并没有共享同一个环境,因此它们是独立的,互不影响。

 

闭包有什么用?

  • 封装
    • 闭包可以实现封装
      • 技术分享
      • 在这个例子里,observer是一个闭包,也是一个对象。这个对象中的属性是访问observerList这个私有变量的接口。外部无法直接访问或操作observerList,只有通过提供的接口才能实现对observerList的访问和操作。

 

循环中创建闭包

请看下面一个例子:

技术分享

  这个函数会返回一个函数数组。表面上看,似乎每个函数都会打印自己的索引值。但实际上每个函数都打印10。因为每个函数引用的都是同一个变量i.当foo()函数返回后,i的值变为10,所以每个函数执行时结果都为10.

通过创建另一个匿名函数,可以让闭包的行为符合预期。

技术分享

 

 

性能问题

  函数执行后,若函数中的变量被外部函数所引用(即产生闭包),则该变量并不会被JS的垃圾回收机制所回收,而是保存在内存中。

引用自MDN中的资料:

     如果不是因为某些特殊任务而需要闭包,在没有必要的情况下,在其它函数中创建函数是不明智的,因为闭包对脚本性能具有负面影响,包括处理速度和内存消耗。

例如,在创建新的对象或者类时,方法通常应该关联于对象的原型,而不是定义到对象的构造器中。原因是这将导致每次构造器被调用,方法都会被重新赋值一次(也就是说,为每一个对象的创建)。

学习JS闭包

标签:

原文地址:http://www.cnblogs.com/seven-zh/p/4571020.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!