Why does doSomething() function call work while doSomethingElse() does not?
That will only be true if the code you've shown isn't at global scope (the code in your fiddle is wrapped in an onload
handler provided by jsFiddle itself, see the options on the JavaScript pane — this is one of jsFiddle's more ridiculoussurprising default options). The reason is what I call The Horror of Implicit Globals. By not declaring doSomething
in this code:
doSomething = function() {
alert(this);
}
...you're creating a global variable called doSomething
. But by declaring doSomethingElse
in this code:
var doSomethingElse = function() {
alert(this);
}
...you're creating a local variable in the scope where that code exists.
Why does it matter? Because any function you call in an old onXYZ
-attribute-style event handler has to be a global.
Instead:
Use strict mode ("use strict"
) so that assigning to an undeclared identifier is an error instead of creating an automatic global.
Use modern event handling (addEventListener
and such) rather than onXYZ
-attribute-style event handlers that require global functions.
Put your script
tag at the end of the document body, just before the closing </body>
tag, so that all elements defined by your HTML have been created before the code runs. (Then you don't need onload
or similar handlers.)
For example (Stack Snippets put the automatic script
tag at the end of body
for you):
"use strict";
// Scoping function to avoid creating globals
(function() {
var doSomething = function() {
console.log("doSomething");
};
var doSomethingElse = function() {
console.log("doSomethingElse");
};
document.getElementById("button1").addEventListener("click", doSomething);
document.getElementById("button2").addEventListener("click", doSomethingElse);
})();
<div id="banner-message">
<p>Hello World</p>
<button id='button1'>Do Something</button>
<button id='button2'>Do Something Else</button>
</div>