2013-07-04 24 views
6
<input type="button" value="Button 1" id="btn1" /> 
<input type="button" value="Button 2" id="btn2" /> 
<input type="button" value="Button 3" id="btn3" onclick="buttonClicked();"/> 


<script type="text/javascript"> 

    function buttonClicked(){   
    var text = (this === window) ? 'window' : this.id;  
    console.log(text);   
    } 

    var button1 = document.getElementById('btn1'); 
    var button2 = document.getElementById('btn2'); 


    button1.onclick = buttonClicked; 

    button2.onclick = function(){ 
    buttonClicked(); 
    }; 

</script> 

問:試圖弄清楚 '這' 在一些JS代碼

當單擊Button1,顯示:btn1,單擊按鈕2和按鈕3,說明:window,爲什麼不btn2btn3

+6

您應該閱讀[關於**這個**關鍵字](http://www.quirksmode.org/js/this.html) – doppelgreener

+0

儘管QuirksMode頁面很好地解釋了它,但我並不完全確定是否「複製」是正確的詞。它不復制函數,只是複製一個引用。調用上下文是爲函數執行上下文設置'this'引用。 –

+0

你可以很容易地檢查該功能是否被*複製*爲button1.onclick = buttonClicked; console.log(button1.onclick === buttonClicked);'函數是對象,對象之間的等式比較只在兩個引用指向同一個對象時才返回true。 –

回答

4
button1.onclick = buttonClicked; 

它顯示btn1因爲的onclick(按鈕1的屬性)現在指向buttonClicked,所以這個調用的上下文是button1

button2.onclick = function(){ 
    buttonClicked(); 
    }; 

它顯示window,因爲的onclick現在(一BUTTON2的屬性)指向一個匿名函數,而函數調用buttonClicked();(類似於window.buttonClicked();)內,這個調用的上下文是window

你的情況與BUTTON3:

<input type="button" value="Button 3" id="btn3" onclick="buttonClicked();"/> 

等同於:

btn3.onclick = function(){ 
    buttonClicked(); 
} 

因爲當你在線聲明的事件處理程序,瀏覽器會自動包裝了一個匿名函數內部的代碼。

1

基礎

當點擊處理程序是這樣定義的:

button.onclick = some_function; 

當單擊該按鈕時,JavaScript的將真正運行這個命令:

some_function.call(button, ...); 

換句話說,在處理程序中將對按鈕元素的引用綁定爲this

匿名函數

讓我們來看看定義的button2單擊處理程序:

button2.onclick = function() { 
    buttonClicked(); 
} 

匿名函數被綁定到該按鈕,但buttonClicked()呼叫沒有在所有綁定(所以它含蓄地約束於window的範圍)。爲了達到你需要做的這個預期的結果:無論你寫裏面的onclick屬性被用作體單擊處理的

button2.onclick = function() { 
    buttonClicked.apply(this, arguments); 
} 

在線

。所以,你的代碼:

<input ... onclick="some_function();" /> 

等同於:

button3.onclick = function() { 
    some_function(); 
}; 

正如你可以看到,它的行爲一樣button2

獎金

對於它的樂趣,你可以寫你的網線單擊處理程序是這樣的:

<input ... onclick="buttonClicked.call(this);" /> 

Results

順便說一句,寫事件處理程序內聯是不是一個很好的練習,你應該看看使用addEventListener()attachEvent()(IE)註冊它們,但請注意它們的行爲不同。

相關問題