JavaScript function declaration ambiguity
Now say the title of this post ten times in a row, five times as fast… yea, anyway. This is meant to be a short and sweet tip about how you declare your functions in JavaScript; mainly because there is a little white lie floating out there that says that the two declarations are synonymous. But one is just shorthand for the other. Here they are represented in code:
two supposed synonymous declarations
// regular declaration
function foo() {
// body...
};
// shorthand
var foo = function() {
// body...
};
In reality, nothing is actually wrong with using either style, and they both work. However, there is one very basic situation where the shorthand style won’t yield the result you’re looking for, and the reason is fairly obvious and simple. Only the first one is an actual function declaration, whereas the shorthand method is just a regular variable declaration with an anonymous function assigned to it as its value. Here is the most basic scenario:
variable defining
var foo = 'bar';
alert(foo); // alerts 'bar'
alert(baz); // alerts 'undefined'
var baz = 'thunk';
The results of this scenario is trivial, but it proves the point. The second alert shows ‘undefined’ because the variable hasn’t been defined yet. Well, the same goes with functions when you’re assigning them to a variable. You can’t use them, until you’ve defined them (if you’re using shorthand). But with regular function declarations, the JavaScript interpreter knows to fetch the functions when it needs them, even if they aren’t declared until further parts in your code. Again, here is a basic scenario;
declaring functions before and after
sayHello(); // alerts 'Hello World'
function sayHello(){
alert('Hello World');
};
sayGoodbye(); // throws error. sayGoodbye is not a function
var sayGoodbye = function() {
alert('Goodbye World');
};
Lesson learned?
Just use regular function declarations all the time? Well, ok, I guess. The obvious use of using variable declaration is that you are indeed assigning ’something’ to a variable, and a key takeaway is that you can immediately self-invoke the anonymous function and return a different value back to it. This technique as I’ve discussed several times on this blog already is known as the modular format which is most commonly used for information hiding. As to why that’s important, you’ll hear why when my book gets published.













February 22nd, 2007 at 1:58 am
One other downside of the anonymous functions is that they don’t have a name in a JavaScript debugger. And if you’d like to do
{foo: function foo() { } }, you’ll find it throws a Syntax Error in Safari.February 22nd, 2007 at 4:17 am
Thanks for this article, I need to read the modular format article again though.
Interesting to know you’ve got a book on the way, must have missed that point in your other posts, looking forward to it.
Any idea of the proposed release date?
February 22nd, 2007 at 6:56 am
Does the var keyword hold any significance when used with functions?
February 22nd, 2007 at 10:50 am
Thanks Dustin, that was informative. I could always use more “best practices” types of js tips. Otherwise I tend to just do whatever works.
February 22nd, 2007 at 11:05 am
Mark, you are so correct. I knew I was leaving that out (the fact that functions don’t have names), but didn’t want to adding more weight to the “brief tip.” That’s pretty bogus too that the snippet you wrote throws an error. Does that mean this would throw an error too?
I suppose in the second example, you wouldn’t get the benefit of having a function name anyway, so that’s almost pointless. Anyway, thanks for pointing that out.
Carlton, we’re shooting for this year to have the book released.
Binny, it’s just a different way of doing things, and could keep your code looking more uniform if you feel style is important to you.
Jason, glad you found it useful. Now it’s time to go buy your book!! :o
February 22nd, 2007 at 11:45 am
It’s not always true, if You declare a function using var some version of Internet Explorer has memory limits (function simply doesn’t work if it’s too much big).
A function, in my opinion, should be declared always using regular style; after that You can use a reference variable, if You need them, without problems.
February 22nd, 2007 at 2:37 pm
Another point about creating a function via variable assignment is to be careful of the scope in which it’s created. For example:
In this case, the function
fexists only locally because of the use ofvarwhereasf2is available globally becausevaris omitted.Glad to see you’re back blogging again. Hope the new gig is working out well for you.
February 22nd, 2007 at 3:15 pm
Dustin, those declarations are fine. I believe Safari is following the specification to the letter by throwing the syntax error, while Firefox, IE and Opera are less restrictive. It’s been a while since I looked through the spec though.
February 23rd, 2007 at 3:30 am
Stupid question, but why do you call it shorthand when it’s clearly more to write?
February 23rd, 2007 at 5:49 pm
Also worth knowing is that the var syntax is allowed in some places where a function declaration is not — inside a function, the spec only allows function declarations at the top of the function, whereas you may declare a var keyword later on, mid-function. Most, but not all, browsers handle both, in practice, though.
February 26th, 2007 at 4:27 pm
It’s a well known (I think) matter.
So if I declare
and
I could have different results using them because “func()” and “func” are two separate and different entities, but ambiguous ones.
I guess the result is the important thing!
Right? ;)
February 26th, 2007 at 5:28 pm
Funny, I just prefer to not call my functions until after I’ve defined them.
March 1st, 2007 at 12:13 pm
I have several different web pages generated from PHP that have their own HTML Forms (hopefully only 1 form per page).
I’d like to add a new section to all these forms by simply adding a PHP “include” of this new section or “module”. The module will output HTML and Javascript for this new section.
The “module” has a Javascript validation function specific to this module. How can I get the existing forms to invoke the new module’s validation function (even if the existing forms have validation or not)?
I was trying:
<script language="javascript" type="text/javascript">
<!–
alert("onSubmit BEFORE=" document.forms[0].onSubmit);
if(!document.forms[0].onSubmit){//If onSubmit was undefined
//I would only use one method, but I tried these 2.
//Method 1 - Failed
document.forms[0].onSubmit = "return Mmos_validate();";
//Method 2 - Failed
document.forms[0].onSubmit = function(){
alert("Called Mmos_validate shorthand Function");
return Mmos_validate();
}
}else{
//Method 1, only tested where onSubmit was undefined
document.forms[0].onSubmit = " return Mmos_validate();";
//Will multiple semicolons corrupt the script?
//If it already had an onSubmit with a "return", my code won’t get called anyway.
//Suggestions?
document.forms[0].onSubmit = "; return Mmos_validate();";
}
alert("onSubmit AFTER=" document.forms[0].onSubmit);
function Mmos_validate(){
alert("Called Mmos_validate regular Function");
return false;
}
//–>
</script>
March 1st, 2007 at 2:52 pm
It seems I needed Method 2 and also to use .onsubmit instead of .onSubmit (case sensitive).
March 20th, 2007 at 3:21 pm
Another advantage of using the function name() syntax is that the name property of the variable will be set to the string value of the name (think this.constructor.name when debugging).
On the other hand I am strongly against defining functions after they are used. Since functions aren’t constant you can override them at any time, this could cause some serious confusion even if the behavior is well defined.
Also, your alert(baz) example won’t alert undefined since a “foo is not defined” error is thrown if you try to access an undefined variable, either you were thinking of a property, or you forgot to put var baz; before the alert.
March 26th, 2007 at 3:30 am
Thank you Dustin, I could always use more types of js tips.