上一章咱們講了匿名函數和閉包,此次咱們來談談閉包中做用域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