首页 > 代码库 > javaScript 闭包
javaScript 闭包
什么是闭包
如果不用代码,很难用直观的语言来描述什么是闭包,但是必须要不借助代码理解闭包才是真正从概念上理解,就像说到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 闭包