In the answers to this question, we read that function f() {} defines the name locally, while [var] f = function() {} defines it globally. That makes p
Here's what I think is going on, based on Tim Down's helpful comments and a brief discussion with Jonathan Penn:
When the JavaScript interpreter assigns to the window.onload property, it's talking to an object that the browser has given it. The setter that it invokes notices that the property is called onload, and so goes off to the rest of the browser and wires up the appropriate event. All of this is outside the scope of JavaScript — the script just sees that the property has been set.
When you write a declaration function onload() {}, the setter doesn't get called in quite the same way. Since the declaration causes an assignment to happen at parse time, not evaluation time, the script interpreter goes ahead and creates the variable without telling the browser; or else the window object isn't ready to receive events. Whatever it is, the browser doesn't get a chance to see the assignment like it does when you write onload = function() {}, which goes through the normal setter routine.