2013-07-04 14 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> 

Domanda:cercando di capire 'questo' in alcuni codici JS

quando clic su Button1 mostra: btn1, clic su Button2 e Button3, mostra: window, perché non btn2, btn3?

+6

Si dovrebbe leggere [sulla ** questa ** parola chiave] (http://www.quirksmode.org/js/this.html) – doppelgreener

+0

Anche se la pagina QuirksMode lo spiega molto bene, non sono completamente sicuro se "copiare" è la parola giusta. Non copia la funzione, copia semplicemente un riferimento ad essa. Il contesto di chiamata è ciò che imposta il riferimento "this" per il contesto di esecuzione della funzione. –

+0

E si può facilmente verificare che la funzione non sia * copiata * come 'button1.onclick = buttonClicked; console.log (button1.onclick === buttonClicked); 'funzioni sono oggetti e i confronti di uguaglianza tra oggetti restituiscono true solo se entrambi i riferimenti puntano allo stesso oggetto. –

risposta

4
button1.onclick = buttonClicked; 

Essa mostra btn1 perché onclick (una proprietà di button1) ora punta buttonClicked, quindi il contesto di questa chiamata è button1

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

Essa mostra window perché onclick (una proprietà di button2) ora punta a una funzione anonima, e all'interno di quella funzione si chiama buttonClicked(); (simile a window.buttonClicked();), il contesto di questa chiamata è window

Il tuo caso con button3:

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

è equivalente a:

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

Perché quando si dichiara vostri gestori di eventi in linea, il browser si avvolge automaticamente il codice all'interno di una funzione anonima.

1

Basics

Quando un gestore di clic è definita in questo modo:

button.onclick = some_function; 

Mentre il pulsante viene premuto, JavaScript sarà effettivamente eseguire questo:

some_function.call(button, ...); 

In altre parole, un riferimento all'elemento button è associato come this all'interno del gestore.

Anonymous funzione

Guardiamo la definizione per il gestore di un clic del button2:

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

La funzione anonima viene legato al pulsante, ma la chiamata a buttonClicked() non è vincolata a tutti (quindi implicitamente è legato allo scope di window). Per ottenere i risultati attesi che devi fare questo:

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

Linea

ciò che si scrive all'interno dell'attributo onclick viene utilizzato come corpo del gestore click.Quindi, il tuo codice:

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

è equivalente a:

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

Come si può vedere, si comporterà lo stesso di button2.

Bonus

Per il gusto di farlo, si potrebbe scrivere il vostro scatto gestore linea come questa:

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

Results

Btw, scrivendo gestori di eventi in linea non è molto buona pratica e si dovrebbe guardare registrandoli utilizzando addEventListener() o attachEvent() (IE), ma si noti che si comportano in modo diverso.

Problemi correlati