闭包
来源:互联网 发布:极客邦科技软件 编辑:程序博客网 时间:2024/06/11 13:19
1.什么是闭包
有权访问另一个函数作用域内变量的函数都是闭包。
2.变量解析
每次定义一个函数,都会产生一个作用域链(scope chain)。当JavaScript寻找变量varible时(这个过程称为变量解析),总会优先在当前作用域链的第一个对象中查找属性varible ,如果找到,则直接使用这个属性;否则,继续查找下一个对象的是否存在这个属性;这个过程会持续直至找到这个属性或者最终未找到引发错误为止。JavaScript中的闭包其实很简单,根本上还是变量解析。而之所以可以实现,是变量解析会在作用域链中依次寻找对应属性的导致的。
Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。另一方面,在函数外部自然无法读取函数内的局部变量。既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗.
function f1(){ var n=999; function f2(){ alert(n); } return f2; } var result=f1(); result(); // 999
3.闭包
function a(){ var n = 0; function inc() { n++; console.log(n); } inc(); inc(); }a(); //控制台输出1,再输出2
function a(){ var n = 0; this.inc = function () { n++; //inc 函数访问了构造函数 a 里面的变量 n,形成了一个闭包 console.log(n); };}var c = new a();c.inc(); //控制台输出1c.inc(); //控制台输出2
function a(){ var n = 0; function inc(){ n++; console.log(n); } return inc;//因为在 a 函数外部无法直接调用 inc 函数,所以 return inc 与外部联系起来}var c = a();//a()返回的是函数inc,这句等同于 var c = inc; c(); //c(),等同于 inc()c(); //函数名只是一个标识(指向函数的指针),而()才是执行函数。
a是inc的父函数,而inc被赋给了一个全局变量(return inc;),这导致inc始终在内存中,而inc的存在依赖于a,因此a也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。
4.总结
闭包就是一个函数引用另外一个函数的变量,因为变量被引用着所以不会被回收,因此可以用来封装一个私有变量。这是优点也是缺点,不必要的闭包只会徒增内存消耗!
闭包基础:http://www.cnblogs.com/qieguo/p/5457040.html
闭包详解:http://www.cnblogs.com/xiaotie/archive/2011/08/03/2126145.html
阮一峰讲闭包:http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html