# JS Tip of the Day: Attribute Event Scopes

**URL:** https://forum.kirupa.com/t/js-tip-of-the-day-attribute-event-scopes/643139
**Category:** web dev
**Created:** [March 28, 2020, 1:57pm UTC](https://forum.kirupa.com/t/js-tip-of-the-day-attribute-event-scopes/643139 "2020-03-28T13:57:52Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![senocular](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/senocular/32/7217_2.png) [@senocular](https://forum.kirupa.com/u/senocular)
#### Post date: [March 28, 2020, 1:57pm UTC](https://forum.kirupa.com/t/js-tip-of-the-day-attribute-event-scopes/643139/1 "2020-03-28T13:57:52Z")

</div>

**Attribute Event Scopes**  
Level: Intermediate

We’ve seen how event attributes in HTML create functions in JavaScript that get assigned to the element’s respective event callback property. But there’s actually a lot more to how this function gets created than you may realize. Specifically, what you don’t see are the scopes involved in creating that function. Scopes determine what variables are available to the function that aren’t local to the function itself. All functions have access to the global scope, but they would also have access to any other scopes they were in when they were defined.

Unfortunately, you don’t exactly see how or where callback functions for attribute events are defined. So it’s not something you’d be able to identify through source code as you might be able to with your other functions. But that’s ok, because I’m about to show you exactly how it might look right now.

Here, we’re going to be using a `<button>` element represented as `button` that has been given an `onclick` attribute to demonstrate. The creation of the respective `onclick` callback function on the element object would look something like this:

```javascript
with (document) {
    with (button.form) {
        with (button) {
            button.onclick = eval(`(
                function onclick (event) {
                    ${button.getAttribute('onclick')}
                }
            )`);
        }
    }
}

```

Immediately you should be able to recognize the collection of `with` blocks leading to the actual `onclick` assignment. This represents the extra scopes that the function is defined with. What this means is that if you use the name of a property in either `document`, `button.form` (i.e. a `<form>` ancestor of the `<button>`), or the `button` element itself in the onclick function, you’ll be referencing the respective property in any one of these objects.

```auto
<button onclick="console.log(doctype)">
    Log doctype
</button>
<!-- click:
<!doctype html> (<- document.doctype)
-->

```

While this can be convenient, especially for easily accessing properties of the `button` directly, it can also be confusing, notably when trying to access would-be global properties that might share a name with any of the properties in any of these objects.

```auto
<script>
let method = 'Credit card';
</script>
<form>
    <button onclick="console.log(method)">
        Log method
    </button>
</form>
<!-- click:
get (<- form.method)
-->

```

Here, though you might expect to be referencing the `method` declared in the `<script>` tag, you’re actually referencing the method in the `<form>` element the `<button>` is a child of. This will happen for _every_ property within _each_ those object, of which there are many.

For this reason, if you’re using event attributes at all (which is not really recommended anyway), you’re better off calling functions in those attributes that you’ve defined somewhere else, rather than relying on code defined directly within the attribute. Just make sure the function you call also does not clash with any of those object properties.

```auto
<script>
function logMethod (event) {
    console.log(method);
}
let method = 'Credit card';
</script>
<form>
    <button onclick="logMethod(event)">
        Log method
    </button>
</form>
<!-- click:
Credit card
-->

```

More info:

- [Defining a handler in WHATWG spec](https://html.spec.whatwg.org/multipage/webappapis.html#internal-raw-uncompiled-handler)
