2009-07-14 82 views
2

示例代碼:JavaScript本不指向正確的對象

function TestClass() { 

this.init = function() { 

    this.updateHeader(); // <-- error line 

}; 

this.updateHeader = function() { 
    console.log("Works"); 
}; 

}; 
var test = new TestClass(); 
$(document).ready(test.init); 

當我運行在Firefox 3.5,螢火蟲給我一個錯誤,說this.updateHeader是不是有效的函數。我是Java/PHP程序員,並且在理解Javascript OO模型時遇到了一些麻煩。我究竟做錯了什麼?

如果用簡單的test.init()替換$(document).ready-line,但它不起作用。

回答

4

通過將函數test.init直接傳遞給ready()函數,您將註冊test.init作爲回調函數。 jQuery(根據您的語法判斷,您正在使用)將使用它提供的回調函數,並且將其應用於document的上下文中。這意味着this關鍵字將引用document

你應該做些什麼來避免這種情況,所建議的,是可以使用匿名函數(關閉),將調用你是指功能:

$(document).ready(function() { 
    test.init(); 
}); 

使用function() { }語法定義閉包來進行設置因爲回調函數是Javascript中的常見模式。

+0

當你想到它,它是有道理的:) – 2009-07-14 20:58:01

1

上下文中的「this」被限定在它所包含的函數中。

1

嘗試$(document).ready(function() { test.init(); });

就緒()期望的功能作爲一個參數,其中,當文檔準備好它將執行。當它發生時,this將指向document對象,而不是test

解決方案是傳遞一個函數,該函數明確調用init,代碼爲test.init()。當您這樣稱呼時,this(在init函數中)指向您的test對象。

3

將test.init提供給文檔ready函數實際上是給它提供了一個指向測試中init函數的函數指針。

本質上它是撕掉init函數並在文檔就緒函數的範圍內執行它。

如果您將它作爲$(document).ready(function(){test.init();})運行; (正如Patrick所說)它會在適當的範圍內執行。