2012-03-10 108 views
0

第二次的結果我已經javascript代碼如下:訪問JavaScript的全局變量未定義

<script type="text/javascript"> 
    var x = 10; 
    window.onload = function() { 
     document.write(this.x); // <-- yields correct output: 10. 
     document.write(this.x); // <-- outputs "undefined" 
     document.write(this.x); // <-- outputs "undefined" 
    } 
</script> 

我無法理解爲什麼[this.x]從第二次起在不確定的結果。如果我是正確的,函數上下文(「this」的值)將引用全局窗口對象。

+1

*輸出「未定義」* - 實際上,它沒有。 http://jsfiddle.net/Tomalak/dt4dg/你正在做一些與你在這裏展示的不同的東西。 – Tomalak 2012-03-10 15:57:48

+0

我只是使用innerHTML將其輸出到DOM元素,或者將其記錄到控制檯 – thescientist 2012-03-10 15:59:36

+0

@Tomalak:我絕對是積極的,我寫的是我正在做的:)。我寫這段代碼的意圖是理解「這個」。如果我錯了,請指向正確的方向。謝謝。 – 2012-03-10 16:03:02

回答

2

當您使用document.write()加載文檔後,它會打開一個新文檔(清除前一個文檔)。看起來,在某些瀏覽器(例如IE)中,全局變量會立即被清除,即使是仍在運行的腳本也會被刪除,即document.write()。這裏最好的答案是在頁面加載後不使用document.write()。相反,使用DOM操作來更改現有文檔,但希望更改它而不是創建新文檔。如果使用DOM操作(操作innerHTML),而不是在this jsFiddle中使用document.write(),則可以看到事情工作正常(基於最近的代碼示例)。

由於清除當前文檔幾乎從不是你想要做的,如果你能解釋你真正想要完成的事情,我們可以更好地解決問題。

如果您想在modify已加載的現有文檔之後,您需要使用DOM操作功能,如.innerHTML(用於更改節點的HTML)或DOM操作函數以將新節點添加到現有文檔中,而不是document.write()

您通常不應該使用this來引用全局變量。全局變量不帶前綴(除非本地覆蓋)或可用前綴window

因此,任何一項都將工作:

<script type="text/javascript"> 
    var x = 10; 
    window.onload = function() { 
     console.log(x); 
     console.log(x); 
     console.log(x); 
    } 
</script> 

<script type="text/javascript"> 
    var x = 10; 
    window.onload = function() { 
     console.log(window.x); 
     console.log(window.x); 
     console.log(window.x); 
    } 
</script> 

至於你的問題有關使用this。的this值被設定的幾種方法之一:

  1. 當你調用一個方法,如pleasures.makeIceCream()this值將被設置爲在makeIceCream()方法pleasures對象的對象上。
  2. 當您在函數對象如makeIceCream.call(pleasures)上使用call方法時,在調用makeIceCream()方法時,this的值將設置爲pleasures對象。
  3. 當使用上功能對象apply方法等makeIceCream.apply(pleasures),那麼this值將在這個調用中makeIceCream()方法的設置爲pleasures對象。

你可以閱讀更多有關這些MDN引用.call().apply()

適用於:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/apply

電話:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/call

在所有其他時間的this值一般不應因爲它沒有明確設置。它很可能被設置爲全局對象(在瀏覽器中,這是window對象),但使用它來訪問全局變量並不被認爲是最佳實踐,也沒有任何理由。

+0

我同意你對這個概念的理解,並且我會在我的項目中使用最佳實踐。但正如你所說的:「在其他任何時候,」this「都會引用全局對象」,我只想了解,第二次訪問document.write(this.x)時出現了什麼問題。對於這個例子,我關注的是概念,而不是最佳實踐。我希望你能理解我的擔憂。如果我寫「alert」而不是「document.write」,它可以正常工作。 – 2012-03-10 16:36:34

+0

你可以看看這段代碼嗎? http://jsfiddle.net/AnupVasudeva/SJn5m/7/ – 2012-03-10 16:58:22

+0

@AnupVasudeva - 當創建一個全新的文檔時,可能是第一個'document.write()'清除了現有文檔(在某些瀏覽器中)及其所有全局變量。因此,曾經作爲全局對象存在的任何東西都不再存在。正如我已經說過四次,現在在文檔加載後不要使用'document.write()'。這是什麼部分我沒有有效地溝通? – jfriend00 2012-03-10 17:32:01

0

我只想用這樣的:

document.write(x); 

既然是它可以在函數中調用該函數的定義之外。

+0

在x前加上「this」是否有任何問題? – 2012-03-10 16:04:19

1

因爲它是一個全局變量,所以不需要使用object。試試這個

var x = 10; 
window.onload = function() { 
    document.write(x); 
    document.write(x); 
    document.write(x); 
} 

小提琴:http://jsfiddle.net/dt4dg/1/

+0

謝謝rajkumar。我知道這很好。但我試圖找出爲什麼document.write(this.x)不起作用的原因。當調用window.onload函數時,函數上下文(this)將始終是一個窗口對象。 – 2012-03-10 16:08:46

0

這是行不通的,因爲你的頁面加載後調用文件撰寫。調用write將隱含地表示您正在創建一個新頁面。新頁面不理解x的值。

+0

,但它似乎是理解「document.write(x)」而不是「document.write(this.x)」。兩者有什麼區別? – 2012-03-10 16:29:27