JS闭包

2016-09-30  本文已影响0人  树袋熊熊

javascript闭包 对我来说是一个难点,结合阮一峰老师,书籍以及同学的总结和建议写的这一篇笔记。在我看来 闭包 作用域 垃圾回收机制 函数嵌套 有关。

首先闭包为什么会产生,他到底是解决什么问题?

首先看一段代码:

var n=2;

function a (){

alert(n);

}

a()         //此时返回2

结果为什么是2呢?    ====>   n为全局变量

再看一段代码:

function a(){

var n=2;

}

alert(n)      //error

结果为什么是error呢?   ===>  n为局部变量

这个是 变量作用域  的问题:变量作用域分为 全局变量  局部变量(对其的理解在作用域及作用域链中)

那么你要读取函数的内部变量应该怎么解决?(1)

这是一个问题!

其次,看下面的代码:

var n=2;

function a (){

alert(n);

}

a()         //此时返回2

a()        //此时返回2

为什么得到的结果不是下面这样呢?

a()        //此时返回2

a()        //此时返回3

这个是javascript的垃圾回收机制问题:一个函数在执行开始的时候,会给其中的定义的变量划分内存空间保存,以备后面的语句所用,等到函数执行完毕后返回,这些变量就被认为是无用了,对应的内存空间就被回收了,再次执行时,所有的变量变为最初状态。

那么想要本次的执行结果是继承在上次的执行结果的基础上的呢?(即想让该变量长期的保存在内存中应该如何解决?)(2)

为了解决(1)(2)的两个问题所以引进了闭包。

所以引出闭包的作用:一个是读取函数内部变量,另一个是让变量的值始终保存在内存中。

既然闭包可以解决这两个问题,那么是怎样解决的呢?

function  a(){

   var n="Mozilla";

   function displayName({

        alert(n);

}

return displayName;

}

var myFunc=a();

myFunc();

这里用到的是 函数嵌套 :函数内部又嵌套了另一个函数,而内部函数又使用了外部函数的某些变量,这是垃圾回收机制就会出现问题。

此时javascript解释器在遇到函数定义的时候,会自动把函数和其他可能用到的变量一起保存起来,构成了闭包,只有当内部函数不被调用后,才销毁这个闭包。

其实在写闭包的时候也可以用到匿名函数。===>匿名函数:无需定义函数名的函数或者子程序。看下面的代码助于理解:

function a(){

    var n = 'rain-man';

    setTimeout(function(){ alert(n); } //这是一个匿名函数

, 2000);

}

a();

我用到的是ES6,所以上面的匿名函数就变为:

setTimeout( ()=>{ alert(n); } //这是一个匿名函数 , 2000);

当然闭包存在一些问题:

   一个是因为闭包使函数中变量都保存在内存中,内存消耗很大。

   另一个是在IE下可能导致内存泄露。(我理解的内存泄露是 页面跳转时变量不会释放,直到浏览器关闭才会释放。比较权威的解释是:一块被分配的内存,即不能使用,又不能被回收,直到浏览器进程结束)。

如何去注意点这些问题:

对于内存消耗大的问题,就要求我们不能滥用闭包,否则会造成网页的性能问题。

对于IE下的内存泄露问题:退出函数前,将不使用的局部变量全部删除。主要使用window.onunload.具体可以参照js内存泄露问题


闭包-知乎

闭包-阮一峰

上一篇下一篇

猜你喜欢

热点阅读