Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"this" inside event handler from HTML attribute

I thought I understood wel the "this" keyword until I saw this code :

<body>
    <button onclick="go()">clic1</button>

    <button id="btn">clic2</button>

    <script>

        function go() {
            console.log(this);
        }

        var btn = document.getElementById("btn");
        btn.onclick = function() {
            console.log(this)
        }

    </script>
</body>

I have a HTML document with two buttons that do the same thing when clicked :they log the "this" keyword.

I'm very surprised they don't show the same result :

For the button "clic1" : this = Window

For the button "clic2" : this = the button object with id "btn"

Is there any explanation for that ?

Thank you

like image 232
AntonBoarf Avatar asked Jul 05 '26 02:07

AntonBoarf


1 Answers

TLDR:

go is not the event handler of the first button. The event handler is an anonymous function generated by the HTML parser. In the example, the generated handler just happens to call go.


JavaScript code provided in HTML for an onEventName attribute is compiled into a function of form

function(event) {
    // code written in the attribute value
}

Functions generated by the parser in this way have a rather strange scope chain which includes the element the generated handler is a property of, any outer form element the element is within, and the document object, at least. Reasons for the scope chain date back to before the DOM was standardized. Older IE releases provided window.event instead of the event parameter.

So the first button

 <button onclick="go()">clic1</button>

in current browsers generates the button's onclick handler as:

 function( event) {
     go()
 }
  • the onclick handler is the function taking the event parameter. It is called with a this value of the button.

  • go is an ordinary function call - the this value of the caller has not been applied. You could, say, pass on this as a parameter by calling go(this) if you wanted to.

  • go was declared using the function keyword and by default has a this value of the global object.

  • If you must attach a [myHandler] function in HTML to be called like an event handler, add an attribute in the opening tag like

    oneventname = "myHandler.call(this, event)"
    

    or provided the this value is not required, simply

    oneventname="myHandler(event);
    

In the second example, you compile an anonymous function expression normally (not using the HTML parser) and attach it directly to the second button element.`

  • the attached function is called with the button as its this value which can be logged to the console.

  • the attached function does not have a wierdo scope chain.

like image 74
traktor Avatar answered Jul 06 '26 16:07

traktor



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!