79747667

Date: 2025-08-27 07:39:57
Score: 0.5
Natty:
Report link

ok, 6 years of this question playing on my mind, and today I ran into a similar problem and decided to address these once and for all, although spoiler the onload answer is not as satisfying

the window.onload is actually a getter/setter and it is the setter function that actually registers the event handler, all event handlers are getter/setter ie div.onclick

<script src='https://javascript-2020.github.io/stackoverflow/libs/stringify.js'></script>

<div id=output style='font-family:monospace;white-space:pre'></div>

<script>
        
        var desc              = Object.getOwnPropertyDescriptor(window,'onload');
        output.textContent    = stringify(desc);

</script>

only a runtime assignment that goes through the [[set]] operation will invoke the setter defined on window.onload and hence register the handler

when the function onload is declared it overwrites the original property accessor

<script src='https://javascript-2020.github.io/stackoverflow/libs/stringify.js'></script>

<div id=output style='font-family:monospace;white-space:pre'></div>

<script>
        
        var desc              = Object.getOwnPropertyDescriptor(window,'onload');
        output.textContent    = stringify(desc);

        function onload(){}
        
</script>

this is a direct write to the internal property slot, not a JavaScript-level assignment

the ECMAScript spec defines this behavior under Global Environment Records.

tc39.es : Spec Reference: Global Environment Record

when a function is declared in the global scope:

this property is set via internal methods so no setter is triggered



the similar problem i faced today, i was generating some sample html, clicking the submit button enters an infinite loop

<form onsubmit='onsubmit(event)' action='javascript:void(0)'>
      <label for=email>Email address:</label>
      <br>
      <input type=email id=email name=email required value='[email protected]'>
      <br>
      <button type=submit>Subscribe</button>
</form>

<script>

  function onsubmit(e){
  
        alert('you subscribed!');
        
  }//onsubmit

</script>

ok, thats another oddity i thought

turns out javascript uses the string from the tag attribute to generate a function via new Function, and assigns it to the form.onsubmit property, hence

 form.onsubmit    = new Function('event','onsubmit(event)');

then due to function name inference spec introduced in ES2015. tc30.es : SetFunctionName ( name is property name, then 3 )

the function name becomes 'onsubmit', and an infinit loop results, it effectively becomes

form.onsubmit    = function onsubmit(event){onsubmit(event)};


tl;dr

event handler property assignment is a useful tool

when dealing with functions for use as event handler property assignment be careful and either drop the 'on' or declare it as 'onloadh' .. other suggestions welcome in the comments


À tout à l'heure
Reasons:
  • Blacklisted phrase (1): stackoverflow
  • Long answer (-1):
  • Has code block (-0.5):
  • Self-answer (0.5):
  • Low reputation (0.5):
Posted by: matt