闭包

闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的常见的方式,就是在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量。

 

//通过闭包可以返回局部变量

function box() {

       var user = 'Lee';

       return function () {                                    //通过匿名函数返回box()局部变量

              return user;

       };

}

alert(box()());                                                  //通过box()()来直接调用匿名函数返回值

 

var b = box();

alert(b());                                                               //另一种调用匿名函数返回值

 

使用闭包有一个优点,也是它的缺点:就是可以把局部变量驻留在内存中,可以避免使用全局变量。(全局变量污染导致应用程序不可预测性,每个模块都可调用必将引来灾难,所以推荐使用私有的,封装的局部变量)。

 

作用域链的机制导致一个问题,在循环中里的匿名函数取得的任何变量都是最后一个值。

闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的常见的方式,就是在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量。

 

//通过闭包可以返回局部变量

function box() {

       var user = 'Lee';

       return function () {                                    //通过匿名函数返回box()局部变量

              return user;

       };

}

alert(box()());                                                  //通过box()()来直接调用匿名函数返回值

 

var b = box();

alert(b());                                                               //另一种调用匿名函数返回值

 

使用闭包有一个优点,也是它的缺点:就是可以把局部变量驻留在内存中,可以避免使用全局变量。(全局变量污染导致应用程序不可预测性,每个模块都可调用必将引来灾难,所以推荐使用私有的,封装的局部变量)。

 

PS:由于闭包里作用域返回的局部变量资源不会被立刻销毁回收,所以可能会占用更多的内存。过度使用闭包会导致性能下降,建议在非常有必要的时候才使用闭包。

 

作用域链的机制导致一个问题,在循环中里的匿名函数取得的任何变量都是最后一个值。

 

关于this对象

在闭包中使用this对象也可能会导致一些问题,this对象是在运行时基于函数的执行环境绑定的,如果this在全局范围就是window,如果在对象内部就指向这个对象。而闭包却在运行时指向window的,因为闭包并不属于这个对象的属性或方法。

 

var user = 'The Window';

 

var obj = {

       user : 'The Object',

       getUserFunction : function () {

              return function () {                             //闭包不属于obj,里面的this指向window

                     return this.user;

              };

       }

};

 

alert(obj.getUserFunction()());                           //The window

 

//可以强制指向某个对象

alert(obj.getUserFunction().call(obj));                //The Object

 

//也可以从上一个作用域中得到对象

       getUserFunction : function () {

              var that = this;                                                 //从对象的方法里得对象

              return function () {

                     return that.user;

              };

       }

 

内存泄漏

由于IE的JScript对象和DOM对象使用不同的垃圾收集方式,因此闭包在IE中会导致一些问题。就是内存泄漏的问题,也就是无法销毁驻留在内存中的元素。以下代码有两个知识点还没有学习到,一个是DOM,一个是事件。

function box() {

       var oDiv = document.getElementById('oDiv');    //oDiv用完之后一直驻留在内存

       oDiv.onclick = function () {

              alert(oDiv.innerHTML);                             //这里用oDiv导致内存泄漏

       };

}

box();

 

那么在最后应该将oDiv解除引用来避免内存泄漏。

function box() {

       var oDiv = document.getElementById('oDiv');   

var text = oDiv.innerHTML;

       oDiv.onclick = function () {

              alert(text);                                 

       };

oDiv = null;                                                     //解除引用

 

posted @ 2015-11-08 21:02  节操掉尽人清爽  阅读(138)  评论(0)    收藏  举报