闭包的学习
- 闭包就是一个函数引用另外一个函数的变量,因为变量被引用着所以不会被回收,因此可以用来封装一个私有变量。这是优点也是缺点,不必要的闭包只会徒增内存消耗!另外使用闭包也要注意变量的值是否符合你的要求,因为他就像一个静态私有变量一样。闭包通常会跟很多东西混搭起来,接触多了才能加深理解,这里只是开个头说说基础性的东西。
一个小小的实例
function buildList(list) {
var result = [];
for(var i = 0; i < list.length; i++) {
var item = 'item' + list[i];
result.push(
(function(i) {
console.log(item + ' ' + list[i]);
})(i)
);
}
return result;
}
var fnlist = buildList([1,2,3]);
内存泄漏
其实呢,大家所熟知的闭包会造成内存泄漏,就是内存被占用,无法腾出空间做其他的操作。这就牵扯到了浏览器的垃圾回收机制,下面就来说说垃圾回收机制到底是什么东西。
浏览器的垃圾回收机制分为两种;
- 其一:标记清除。具体就是当浏览器运行js时,会给所有的变量,或者占用空间内存的其它东西全部加上标记(就是一个记号,不需要过多研究),执行中当变量被引用到,该变量的标记会被去掉,到最后还存有标记的变量说明已经没有用了,浏览器会把它清除掉,并且收回占用的空间,浏览器会不断地重复执行,所以当变量不用时最终还是会被清除掉,,。而闭包里面的变量受到保护,处于一直被占用状态,也就标记不上了,在内存中也就一直占用
- 其二:引用计数。引用计数的含义是跟踪记录每个值被引用的次数,当声明一个变量并将一个引用类型的值赋给该变量时,这个时候的引用类型的值就会是引用次数+1了。如果同一个值又被赋给另外一个变量,则该值的引用次数又+1。
相反如果包含这个值的引用的变量又取得另外一个值,即被重新赋了值,那么这个值的引用就减一。当这个值的引用次数编程0时,表示没有用到这个值,这个值也无法访问,因此环境就会收回这个值所占用的内存空间回收。这样,当垃圾收集器下次再运行时,它就会释放引用次数为0的值所占用的内存。
如果看到这里还不知道闭包的内存泄漏的话,只有一个原因,那就是闭包内部变量的作用域,还不是很清楚。