淺談Javascript閉包中做用域及內存泄漏問題

上一章咱們講了匿名函數和閉包,此次咱們來談談閉包中做用域this的問題。瀏覽器

你們都知道,this對象是在運行時基於函數的執行環境綁定的,若是this在全局就是[object window],若是在對象內部就是指向這個對象,而閉包倒是在運行時指向的window,由於閉包並不屬於這個對象的屬性和方法。
咱們先來看一個例子關於全局做用域的問題:閉包

var a = 'this is window';

var box = {
    a:'this is object',
    get:function () {
        return this.a;
    }
};
alert(this.a);        //返回window.由於是全局做用域

不難看出,這個時候,this的做用域是全局的。指向的是window.結合上句話來看例子,若是在對象內部就是指向的這個對象。函數

var a = 'this is window';

var box = {
    a:'this is object',
    get:function () {
        return this.a;
    }
};
alert(box.get());        //返回的是this is object 由於這個是box對象下的做用域

咱們瞭解了做用域的問題。接下來咱們就說說閉包中this對象做用域的問題:this

var a = 'this is window';

var box = {
    a:'this is object',
    get:function () {
        return function () {    //閉包
            retun this.a;    
        };
    }
};
alert(box.get()());        //返回this is window.

這就奇怪了,明明嵌套了這麼多層,怎麼會指向window呢,這就是閉包的機制,仍是剛剛那句話:閉包倒是在運行時指向的window,由於閉包並不屬於這個對象的屬性和方法。指針

那咱們如何講閉包的做用域指針指向對象內部呢?
兩種方法:1.使用call()對象冒充,2.將做用域賦值給變量code

/*對象冒充*/

var a = 'this is window';

var box = {
    a:'this is object',
    get:function () {
        return function () {    //閉包
            retun this.a;    
        };
    }
};
alert(box.get().call(box));    //返回 this is object

使用call()傳值box,將box對象冒充。從而使做用域指向box對象內部。對象

/*將做用域賦值給變量*/

var a = 'this is window';

var box = {
    a:'this is object',
    get:function () {
    /*這裏的做用域是box,而不是window*/
     var scope = this;    //將做用域賦值給一個變量
        return function () {    //閉包
            retun scope.a;    
        };
    }
};
alert(box.get()());    //返回this is object.

IE瀏覽器中內存泄漏問題內存

你們都知道,閉包會使變量駐留在內存中,這也就致使了內存泄漏。可是隻是針對IE瀏覽器,其餘瀏覽器不會出現這種問題.作用域

window.onload = function () {
    function box () {
    var div = document.getElementById('div');
    div.onclick = function () {
        alert(div.innerHTML);
    };
}
box();
};

這裏的互相調用會致使IE瀏覽器內存泄漏,由於div.onclick引用了上面的var div,他倆互相引用致使內存泄漏,解決辦法就是將用完的div賦值null,等待垃圾回收get

window.onload = function () {
    function box () {
    var div = document.getElementById('div');
    var a = div.innerHTML;
    div.onclick = function () {
        alert(a);
    };
    a = null;    //賦值爲null,等待垃圾回收
}
box();
};

若是沒有解除引用,必須等待瀏覽器關閉的時候才能釋放!!!

關於做用域及內存泄漏的文章就到這裏,歡迎老司機指正錯誤!

Brian Lee
相關文章
相關標籤/搜索