利用js的垃圾回收原理来理解闭包(Closure)问题

闭包

官方解释:所谓“闭包”,指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。

个人解释:一个函数a内部包含函数b,这个b即是闭包。调用b的时候,b的作用域链可以找到a的变量对象。

先看个最简单的范例:

function a(){

var v = 1;

return function(){

console.log(v);

}

}

*******假设这个闭包函数为b********

怎么调用b?

a的作用就是return一个b函数,那么我们可以写出这样的表达式:

var  fb = a();

这个fb,即是这个b闭包函数的引用。

fb的作用域链是什么?

在执行a时,会生成一个a函数的活动对象,那么在定义b的时候,作用域链里就会有三个对象的引用:最优先的是b函数本身的活动对象,其次是a函数的活动对象,再次是window。

fb函数如何寻找变量?

它会依次在作用域链存放的三个活动对象里面去找,找到即返回,都没找到返回undefined。

不是说函数执行完了,它的活动对象就销毁了么,照说fb执行的时候,a执行完了,怎么还可以访问里面的值?

Javascript内存回收机制是这样的:

“如果一个对象不再被引用,那么这个对象就会被GC回收。如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。因为函数a被b引用,b又被a外的c引用,这就是为什么函数a执行后不会被回收的原因。”

a的活动对象(存储了它内部的变量)也是对象,当fb的作用域链还存在对它的引用时,无法销毁。也就是说只要fb的引用存在 ,a的活动对象一直保留。

闭包是否更加耗内存?

是的。

使用闭包的好处?

保护闭包外函数内的变量安全。因为只有闭包才能使用。

在内存中维持一个变量,不随着外部函数执行完而销毁。(坏处也是好处)。

这只是我个人总结,要彻底弄懂可能还得翻翻js高级编程第七章。

个人觉得算是懂了。

原文地址:https://www.cnblogs.com/tyhmj/p/2373626.html