js的oop方式和this指针问题
?? js的oop其實很簡單,function本身就充當了類和構造函數的角色。然后通過傳給構造函數的參數,完成類屬性的賦值,從而實際化不同的對象。
?? 可是,js的oop也有很讓人頭疼的地方,其中之一就是this的指向。在js中,普通的函數,this指向的是window對象,因為所有的全局函數都是window對象的方法。而對于類和對象中的方法,this指向的是這個類和對象。可是,this指針并不是那么老實的,如果在一個類中的方法,調用了另一個類的方法,那么這個this的指向就變得很奇怪了。舉個簡單的例子。
var a = 0;
function test()
{
?? this.a=123;
??? this.b = function()
?? {
???? alert(this.a);
?? }
this.init = function()
{
alert(this.a);
??? setTimeout(this.b,1000);
}
this.init();
}
var adang = new test();
你猜結果會是什么?一開始彈出一個123,然后一秒后又彈出一個123??錯!一開始的確是彈出123,一秒后彈出的卻是0!因為setTimeout是window對象的方法,所以做為參數被傳入setTimeout方法的this.b()函數,運行的閉包空間,對象是window,而不再是test類,this指針指向了window,也就是說,里面的alert(this.a)等于window.a,而不是test.a。
?? 這的確有點讓人費解。想來想去,想到的一個解釋是這樣的:因為js中對復雜數據類型是通過傳址方式進行賦值的,所以setTimeout中的第一個參數,也就是要運行的函數,是傳遞的this.b()這個方法的地址給setTimeout方法使用的,這個地址保存的是this.b方法中的所有"字符",是個string!!!然后再在setTimeout內部用eval(str)來運行。這么一來,this關鍵字完全沒有連到test類的地址,而是直接使用新閉包的對象。
?? 這個問題應該怎么解決呢??如果我想在setTimeout里正確運行test類的b方法,正解調用test的屬性,應該怎么做呢?方法很簡單,去掉this,把a由this.a換成var a,讓它從一個公開屬性,變成私有屬性,因為a定義在test內部的最外一級,所以它的作用域是整個test類,類里的b方法可以調用到它。而它又去掉了this關鍵字,不會錯誤地指到別的對象上。
??? 總結一下,心得就是,在用oop方式寫js的時候,少用this關鍵字,除了必要的方法和屬性寫成公開屬性/方法,應該盡量用var 定義成私有屬性/方法。
轉載于:https://www.cnblogs.com/cly84920/archive/2008/07/12/4427145.html
總結
以上是生活随笔為你收集整理的js的oop方式和this指针问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c study_13
- 下一篇: 高等数学(第七版)同济大学 习题5-2