闭包闭包闭包,屁包屁包屁包
一、什么是闭包
javascript里面,所有的函数都是闭包!
这句断言真是惊天地,泣鬼神。不过,通常意义上的闭包是指:某个函数内部的子函数,这个子函数被外界所调用,用于访问父函数(就是那个该死的“某个函数”啦)内的变量(包括参数)。
从中可以看出,我们常常说的闭包是:
1)首先,闭包是一个函数
2)其次,闭包是一个子函数,就是说,它是一个嵌套在函数里的子函数,函数中的函数
3)这个子函数有什么用呢?它会被外界访问,外界通过访问它来访问和操控它所在的父函数中的变量
不过也有一种说法,说闭包是一种特殊的对象,这个对象包括函数和创建该函数的环境。这个环境是指什么呢?我觉得是指父函数中的那些变量。
一个典型的闭包如下:
function a() { var i = 0; function b() { alert(++i); } return b; } var c = a(); c();其中,b就是那个传说中的闭包。
当 函数a 的 内部函数b 被 函数a外的一个变量 引用的时候,就创建了一个 闭包。
二、闭包有什么用
1、外界访问函数内部变量的桥梁
如上所述
好处就是封装,提高私密性
2、保护父函数的内部变量,避免被JS的垃圾回收机制回收
看回开头那个例子:
3、闭包被调用的时候,会如同面向对象中创建实例一样,将父函数的内部变量(包括父函数传入的参数)克隆一份。被调用多少次,就创建多少份,每份都各自独立,互不影响。
看看这个例子:
页面中有如下HTML代码:
为什么会这样呢?
赋给onfocus事件的,是一个个匿名函数。这些匿名函数,使用了父函数setupHelp里的变量 item。因此,从这个意义上来说,这些匿名函数是闭包(别看item是在循环体内定义的,但在父函数setupHelp里,处处都能访问, javascript就是这么怪。可能在javascript里,变量的作用域都是对函数而言的)。当onfocus事件被激发的时候,循环早已结束,此时item因为匿名函数是闭包的缘故,它还存活着,但值是指向helpText最后一项的。而因为那几个匿名函数引用的都是item,因此出现所有提示都相同的情况。
怎么办呢?应该在循环中,将每一次的item都保留下来。
完成这项任务的,还是闭包。因为闭包对变量的保护,无微不至。闭包就是为了操控内部变量而存在。如果世界上有一种爱是真爱,那就是闭包对变量的爱。闭包闭包闭包,屁包屁包屁包。
三、闭包虽好,可别滥用
1、由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2、闭包会在父函数外部,改变父函数内部变量的值。所以一定要小心,不要随便改变父函数内部变量的值。
参考文章:
http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Closures
http://www.jb51.net/article/24101.htm
有一个网站很好,可以在里面写JS、HTML等进行测试
原文:http://blog.csdn.net/leftfist/article/details/41868659