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

Question:essayer de comprendre 'ce' dans certains codes js

quand cliquez sur Button1 montre: btn1, cliquez sur button2 et button3, montre: window, pourquoi ne pas btn2, btn3?

+6

Vous devriez lire [sur le ** mot clé ** this] (http://www.quirksmode.org/js/this.html) – doppelgreener

+0

Bien que la page QuirksMode explique très bien, je ne suis pas tout à fait sûr si "copier" est le bon mot. Il ne copie pas la fonction, copie simplement une référence à celui-ci. Le contexte appelant est ce qui définit la référence 'this' pour le contexte d'exécution de la fonction. –

+0

Et vous pouvez facilement vérifier que la fonction n'est pas * copiée * en tant que 'button1.onclick = buttonClicked; console.log (button1.onclick === buttonClicked); 'les fonctions sont des objets et les comparaisons d'égalité entre objets ne retournent true que si les deux références pointent vers le même objet. –

Répondre

4
button1.onclick = buttonClicked; 

Il montre btn1 parce onclick (une propriété de button1) pointe maintenant à buttonClicked, de sorte que le cadre de cet appel est button1

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

Il montre window parce onclick (une propriété de Button2) maintenant pointe vers une fonction anonyme, et à l'intérieur de cette fonction que vous appelez buttonClicked(); (similaire à window.buttonClicked();), le contexte de cet appel est window

Votre cas button3:

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

est équivalent à:

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

Parce que quand vous déclarez vos gestionnaires d'événements en ligne, le navigateur passe automatiquement votre code à l'intérieur d'une fonction anonyme.

1

Bases

Lorsqu'un gestionnaire de clic est défini comme celui-ci:

button.onclick = some_function; 

Comme le bouton est cliqué, JavaScript taperai en réalité:

some_function.call(button, ...); 

En d'autres termes, une référence à l'élément de bouton est liée comme this à l'intérieur du gestionnaire.

Anonyme fonction

Regardons la définition du gestionnaire de clic de button2:

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

La fonction anonyme se lie au bouton, mais l'appel à buttonClicked() n'est pas lié du tout (donc implicitement est lié à la portée de window). Pour atteindre les résultats escomptés, vous devez faire:

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

Inline

Tout ce que vous écrivez dans l'attribut onclick est utilisé comme corps du gestionnaire de clic.Donc, votre code:

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

est équivalent à:

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

Comme vous pouvez le voir, il se comportera les mêmes que button2.

Bonus

Pour le plaisir, vous pouvez écrire votre gestionnaire de clic en ligne comme celui-ci:

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

Results

BTW, l'écriture de gestionnaires d'événements est en ligne pas un très bon Pratiquez et vous devriez regarder à les enregistrer en utilisant addEventListener() ou attachEvent() (IE), mais notez qu'ils se comportent différemment.