Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript: How is "function onload() {}" different from "onload = function() {}"?

Tags:

In the answers to this question, we read that function f() {} defines the name locally, while [var] f = function() {} defines it globally. That makes perfect sense to me, but there's some strange behavior that's different between the two declarations.

I made an HTML page with the script

onload = function() {
    alert("hello");
}

and it worked as expected. When I changed it to

function onload() {
    alert("hello");
}

nothing happened. (Firefox still fired the event, but WebKit, Opera, and Internet Explorer didn't, although frankly I've no idea which is correct.)

In both cases (in all browsers), I could verify that both window.onload and onload were set to the function. In both cases, the global object this is set to the window, and I no matter how I write the declaration, the window object is receiving the property just fine.

What's going on here? Why does one declaration work differently from the other? Is this a quirk of the JavaScript language, the DOM, or the interaction between the two?

like image 253
Josh Lee Avatar asked Nov 30 '09 08:11

Josh Lee


2 Answers

This two snippets declares a function in the current scope, named "onload". No binding is done.

function onload() { ... }

.

var onload = function() { ... }

This snippet assigns a function to a property/variable/field named "onload" on the current scope:

onload = function() { ... }

The reason why Firefox performed the binding and raised the onload event on the 1st snippet and the others didn't might be because the Firefox chrome (its user interface) itself is written and automated using JavaScript - that's why it's so flexible and easy to write extensions on it. Somehow, when you declared the locally-scoped onload function that way, Firefox "replaced" the window's (most likely the local context at the time) implementation of onload (at that time, an empty function or undefined), when the other browsers correctly "sandboxed" the declaration into another scope (say, global or something).

like image 61
Fábio Batista Avatar answered Oct 18 '22 14:10

Fábio Batista


Many people are correctly pointing out the global / local difference between (UPDATE: Those answers have mostly been removed by their authors now)

var x = function() {

and

function x() {

But that doesn't actually answer your specific question as you aren't actually doing the first one of these.

The difference between the two in your example is:

// Adds a function to the onload event
onload = function() {
    alert("hello");
}

Whereas

// Declares a new function called "onload"
function onload() {
    alert("hello");
}
like image 43
Fenton Avatar answered Oct 18 '22 14:10

Fenton