Trying to figure out 'this' in some js codes
<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:
when you press button1, it displays: btn1 , press button2 and button3, shows: window, why not btn2 , btn3 ?
button1.onclick = buttonClicked; It shows btn1 because onclick (button1 property) now points to buttonClicked , so the context of this call to button1
button2.onclick = function(){ buttonClicked(); }; It shows window because onclick (button2 property) now points to an anonymous function, and inside that function you call buttonClicked(); (similar to window.buttonClicked(); ), the context of this call to window
Your case with button3:
<input type="button" value="Button 3" id="btn3" onclick="buttonClicked();"/> is equivalent to:
btn3.onclick = function(){ buttonClicked(); } Because when you declare event handlers inline, the browser automatically wraps your code inside an anonymous function.
The basics
When the click handler is defined as follows:
button.onclick = some_function; When the button is clicked, JavaScript will actually run this:
some_function.call(button, ...); In other words, the link to the button element is associated with this inside the handler.
Anonymous function
Look at the definition of the button2 click handler:
button2.onclick = function() { buttonClicked(); } An anonymous function is bound to a button, but the buttonClicked() call is not bound at all (therefore, it is implicitly bound to the window ). To achieve the expected results you need to do the following:
button2.onclick = function() { buttonClicked.apply(this, arguments); } Inline
Everything that you write inside the onclick attribute is used as the body of the click handler. So your code is:
<input ... onclick="some_function();" /> It is equivalent to:
button3.onclick = function() { some_function(); }; As you can see, it will behave just like button2 .
Bonus
For the pleasure of this, you can write an inline click handler as follows:
<input ... onclick="buttonClicked.call(this);" /> Btw, writing inline event handlers is not a good practice, and you should look at their registration using addEventListener() or attachEvent () (IE), but note that they behave differently.