码迷,mamicode.com
首页 > 编程语言 > 详细

javaScript 闭包

时间:2014-11-29 22:59:30      阅读:211      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   io   ar   color   os   sp   java   

什么是闭包

  如果不用代码,很难用直观的语言来描述什么是闭包,但是必须要不借助代码理解闭包才是真正从概念上理解,就像说到OO的三大特性,不用任何语言特性而用自然语言来讲述清楚才是真正理解了什么是OO。

  闭包是引用了自由变量的函数。

  狭义上可以这么解释:闭包是一种对象,这种对象包含两部分:

  • 1.函数;
  • 2.创建此函数的上下文。

  也许这个函数只是引用了寄生上下文中的一个变量,但是因为语言设计的问题(变量与函数都是通过执行上下文来索引的),所以函数会引用整个寄生上下文。

  上面的上下文在英文中是指Context,它也被翻译成环境,通常说执行环境更多点。

为什么会创建闭包

  之所以问为什么会创建闭包,而不是问为什么要创建闭包,是因为就算你不知道闭包也会在无意中创建闭包。 

  一般情况下会有更多的疑问,JavaScript说万物皆对象,所以允许函数嵌套,在内层函数引用外层函数的局部变量的事一定会经常发生,为什么要称这种现象为闭包——它毫不起眼,平常不过。

  原因在于JavaScript的执行机制处理这种现象不会像我们写代码那样随便,不管你如何愤怒——因为这就是规则——所以它有了自己的名字:闭包。

  JavaScript的执行流流出一个执行环境时,如果此环境没有被引用,则此环境被销毁——环境中所有的对象都会被销毁。现在考虑闭包,内部环境引用了寄生环境(父环境),然后内部环境被寄生环境返回到寄生环境之外被某个对象OBJ接收,内部环境一般就是一个函数,它引用了外部环境——这样就形成了一个闭包。注意这个引用,其实不说出来,也能知道闭包包含的外部环境肯定只是引用,这意味着,如果在一次执行中依赖同一个自由变量生成多个返回值,这些返回值的计算结果都是以自由变量最后一次的值生成的,这个很绕口,看下面一个例子:

 1 function createFunctions(){
 2     var result = new Array();
 3     for (var i=0; i < 10; i++){//tips:javascript中{}不会生成块级域
 4         result[i] = function(){
 5             return i;
 6         };
 7     }
 8     return result;
 9 }
10 
11 var res = createFunctions();
12 alert(res[5]());//10

 result数组中依次存放了十个函数,函数的返回值是 i,但 i 是 createFunctions 环境中的变量,内部十个函数与此环境生成了十个闭包,但是环境并没有深拷贝10份,闭包中存放的都只是引用而已。当执行流跨出createFunctions时,隶属于它的 i 已经变成了10,这就是res中存放的函数都返回10的原因。

 MDN上的解释是我看过最详细贴切的:closures

javaScript 闭包

标签:style   blog   http   io   ar   color   os   sp   java   

原文地址:http://www.cnblogs.com/magma/p/4132156.html

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