闭包与垃圾回收机制

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了闭包与垃圾回收机制相关的知识,希望对你有一定的参考价值。

一、闭包
1.变量作用域:函数内部可以访问函数外部的全局变量,但是函数外部却无法访问到函数内部的变量。函数内部要使用var声明变量,如果不用,实际上声明的是一个全局变量。
2. 如何从外部读取函数内部的局部变量:有时候我们为了访问到函数内部的局部变量,我们可以在函数内部,再定义一个函数。
``
function f1(){
   var n1=999;
   function f2(){
   alert(n1);
}
}
`` 
以上代码中,函数f1中的所有变量对函数f2都是可见的,但是反过来不行,f2内部的变量对f1都是不可见的。
这就是javascript中的链式作用域结构。子对象会一级一级向上寻找父对象,所以父对象里的变量对子对象都是可见的,但是子对象的变量,父对象无法访问。
代码如下:
``
function f1(){
   var n1=999;
   function f2(){
   alert(n1);
}2017-08-282017-08-28
   return f2;
}
var n=f1();
n();
//等同于:f1()();
``
以上代码中f2函数,就是闭包。
3.闭包的概念:能够访问到其他函数内部变量的函数就是闭包。闭包本质上就是将函数内部和函数外部连接起来的桥梁。
4.闭包的用途:
a.一个是可以读取函数内部的变量,封装的时候就要用到闭包的这一效果。
``
var person = function(){ 
//变量作用域为函数内部,外部无法访问 
var name = "default"; 
return { 
getName : function(){ 
return name; 
}, 
setName : function(newName){ 
name = newName; 


}(); 

print(person.name);//直接访问,结果为undefined 
print(person.getName()); 
person.setName("abruzzi"); 
print(person.getName());

得到结果如下: 

undefined 
default 
abruzzi 

`` 


b.另一个是让变量的值始终保存在内存中,不会在f1函数调用后,被自动清除,这就是缓存功能,如果结果在缓存中,那么直接返回缓存中的对象,如果缓存中没有,再重新执行函数。
因为f1是f2的父函数,f2又被赋给了一个全局变量,这导致f2始终在内存中,又因为f2依赖f1,所以f1也会保持在内存中,不会在函数被调用后被垃圾回收机制清除。

c.避免全局变量污染函数,函数内部用var声明变量,这样外部不会引用到。
##全局变量污染:代码中全局变量过多,导致页面中的代码都共享了这些全局变量,这就会导致变量的使用出现混乱。
5.注意点:闭包会使得函数中的变量被保存在内存中,所以不能滥用闭包,否则会影响浏览器的性能,在ie中会导致内存泄露,解决方法是,在退出函数前,将不使用的局部变量全部删除。

6.删除函数中的局部变量:
``
var f1=(function () {
var n1 = 999;
return {
add: function f2() {
console.log(n1);
},
clear: function f3() {
n1 = null;
}
}
})();
``
外部无法访问到闭包内的变量,但是可以在函数内部返回一个方法,将闭包内部的变量设置为null,让变量失去引用,会被系统自动回收。


二、垃圾回收机制
原理:全局变量的声明周期一直会持续到浏览器页面关闭才会清除,而局部变量只在函数执行器中存在,在这个过程中函数会为局部变量分配相应的内存,来存储它们的值,当函数要使用时才会把变量的值取出来使用,一旦函数结束,局部变量就不再需要了,这时候就会释放它们的内存,清除局部变量。

以上是关于闭包与垃圾回收机制的主要内容,如果未能解决你的问题,请参考以下文章

js闭包和垃圾收集机制

JavaScript中的垃圾回收机制

前端小知识点:JS垃圾回收机制

前端性能优化垃圾回收,闭包,跨域

JS高程中的垃圾回收机制与常见内存泄露的解决方法

垃圾回收机制与内存管理