js闭包和垃圾收集机制

Posted tags:

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

 

1、JS的回收机制

javascript垃圾回收的机制很简单:找出不再使用的变量,然后释放掉其占用的内存,但是这个过程不是实时的,因为其开销比较大,所以垃圾回收系统(GC)会按照固定的时间间隔,周期性的执行。

到底哪个变量是没有用的?所以垃圾收集器必须跟踪到底哪个变量没用,对于不再有用的变量打上标记,以备将来收回其内存。用于标记的无用变量的策略可能因实现而有所区别,通常情况下有两种实现方式:标记清除和引用计数。引用计数不太常用,标记清除较为常用。

 

 

 

 

 

 

  准确来说,闭包是基于正常的垃圾回收处理机制下的。也就是说,一般情况一个函数(函数作用域)执行完毕,里面声明的变量会全部释放,被垃圾回收器回收。但闭包利用一个技巧,让作用域里面的变量,在函数执行完之后依旧保存没有被垃圾回收处理掉。

  可以文字你不太喜欢看,那好,我直接上代码。这可能是很多解说闭包的案列,先拿来用再说

  function foo(x) {

    var tmp = 3;
    return function (y) {
        alert(x + y + (++tmp));
    }
  }
  var bar = foo(2); // bar 现在是一个闭包
  bar(10);

 我们来分析一下这一段代码,在foo中,声明一个变量tmp,他属于foo作用域下的变量。函数返回一个函数,这个函数被嵌套,函数内部弹出x+y(++tmp)。这是个人都看得懂啊,那为什么会出现闭包,怎么出现的了。这接下来就是看执行的过程了,首先执行var bar = foo(2);那么foo就执行了,参数2也传进去了,但是执行完毕之后,tmp变量以及参数x就已经被释放回收了吗?并没有,因为返回值里面还等待使用这些变量咯,所以此时,foo虽然执行了,但是foo的变量并没有被释放,在return在等待继续使用这些变量了,这个时候bar就是一个闭包。

 

 

 

要理解闭包,首先必须理解Javascript特殊的变量作用域。

变量的作用域无非就是两种:全局变量和局部变量。

Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。

链式作用域,其实就是Javascript的一个特性:子函数中可以访问父函数的所有变量,父对象的所有变量,对子对象都是可见的,反之则不成立。

 

 

js code:

var n = 999;

function f1(){

  console.log(n);

}

f1();  //999

 

 

另一方面,在函数外部自然无法读取函数内的局部变量。

 

 

 

function f1(){

  var n = 999;

}

console.log(n);  //error

这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量。

 

function f1(){

  n = 999;

}

f1();

console.log(n);  //999

二、如何从外部读取局部变量?

出于种种原因,我们有时候需要得到函数内的局部变量。但是,前面已经说过了,正常情况下,这是办不到的,只有通过变通方法才能实现。

那就是在函数的内部,再定义一个函数。

 

function f1(){

  n = 999;

  function f2(){

    console.log(n);  //999

  }

}

 

 

 

 

https://www.cnblogs.com/JIANGCHEN520/p/7118656.html

 

https://blog.csdn.net/michael8512/article/details/77888000

 

https://www.cnblogs.com/duanlianjiang/p/5036671.html

 

https://www.cnblogs.com/duanlianjiang/p/5036671.html

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

闭包会造成内存泄漏吗?

闭包会造成内存泄漏吗

前端开发中javascript闭包会引发内存泄漏么?

js之认识闭包

JavaScript中的垃圾回收机制

js闭包详细讲解