Awkard Looking JavaScript
I’d like to think I have a pretty good grasp on the JavaScript langauge. And for the most part, I know how to write well-organized JavaScript and of course I know how most of the syntax looks like including control stuctures, where to insert semi-colons, comma’s, curley braces, and square brackets. Plus there’s the notations such as dot notation, subscript notation, both of which can make up object notation. Then there’s different ways to set up functions and where you can insert parenthesis or declare anonymous functions. Oh then there’s closures which are inner functions…
Ok, straight and to the point. Douglas Crockford writes about private properties and methods within the JavaScript language. Simple enough. I buy it, and, well of course, it makes sense too. There was one thing however that caught my attention. But this has nothing to do per sé with Douglas’ discussion on private methods. It has to do with self-invoking functions and the similarities between how a function can be constructed.
Here is the example quoted as per Crockford:
function constructs
/* Note: The function statement */
function membername() {
// do stuff here
}
/* is shorthand for */
var membername = function() {
// do stuff here
};
Cool. Makes perfect sense. Now let’s introduce some self-invoking behaviors to these two types of styles.
self-invoking function examples
(function i_am_anonymous(me) {
alert(me);
}('one'));
(function i_am_anonymous() {
alert('two');
}());
// hell, why even have a function name
(function() {
alert('three');
}());
var so_what_am_i = function(me) {
alert(me);
}('huzzah');
Ok now, first off all, self-invoking syntax is the wierdest looking syntax in the JavaScript language. That may be partly because I don’t have CS degree. Nevermind the matter, take special note to the final example where we declare what_am_i as a function. Is it in the global space? Is it in an anonymous space? You sure as heck can’t call who_am_i. Or wait, yes, you can… once. And you’re running it in the act of declaring it. Hence forth, self-invoking.
What’s all this mean?
Nothing really. I just thought I’d point it out. Nothing special. I can talk about the usefulness of closures. But I’ll save that for later. So for now, just be enlightened with this knowledge (or confused). Ciao.




April 13th, 2006 at 2:13 am
Doesn’t “so_what_am_i” take the value returned by the anonymous function, once called with the parameter “huzzah” ?
Trying this, we get a alert of “huzzah” :
var so_what_am_i = function(me) {
return me;
}(’huzzah’);
alert(so_what_am_i);
April 13th, 2006 at 4:01 am
.. why not use an if statement instead? Wouldn’t that be easier to read and just as efficient/usable to get the same end result?
Seems to me that the few lines of extra code you might need make up for the stuff the self proclaiming function does would thoroughly increase read-ability..
April 13th, 2006 at 4:32 am
You can make recursive calls within an anonymous function using arguments.callee , which is a reference to the currently executing function (even if it has no name).
April 13th, 2006 at 7:47 am
Anonymous functions are private functions, by virtue of the fact that nobody can invoke them. Seems like a hack, but still cool.
You can even get really crazy and create anonymous (private) functions that self invoke an object literla, hence making private object literals…
(function (){
var the = {
thing:’scary monster’,
attach:function(){
alert(the.thing);
}
}
the.attach();
}())
April 13th, 2006 at 9:00 am
aaaaaaAAAAAAAHHHHH!
*runs in circles*
April 13th, 2006 at 8:58 pm
So what’s the practical difference between these?
var membername = function() {};
var membername = function membername() {};
var membername = function differentname() {};
April 14th, 2006 at 3:17 am
I just found another way of calling anonymous functions:
void function(me) {
alert(me);
}(’huzzah’);
April 14th, 2006 at 5:56 am
I think that this is actually how the first example should look…notice the removal of the word ‘membername’ from the second version:
/* Note: The function statement */
function membername() {
// do stuff here
}
/* is shorthand for */
var membername = function() {
// do stuff here
};
Am I right? Or is that just another of the ways you can define a function?
April 14th, 2006 at 5:59 am
I think the reason you can’t call ‘who_am_i’ is because you never declared it.
April 14th, 2006 at 7:00 am
…look here
var so_what_am_i = function(me) {
alert(me);return me
}(’huzzah’)
alert(so_what_am_i)
did you understand?
you are not assign the function but an istance of the function, so it return undefined because you have no return in it.
you can’t call so_what_am_i
because you have no pointer to that function.
like
function(){
alert(”can’t be called”)
}
April 14th, 2006 at 8:31 am
Jim, I can’t believe you were the first to point that out. I corrected it, so good catch.
As for the
so_what_am_ifunction, it’s self-invoking, and that’s the one and only time it gets called. If we removed the last () parenthesis and put a return value, then yea, we can do something with it :)April 14th, 2006 at 10:12 am
The value of this syntax is that you can create single-use immediately-run code without polluting the global namespace.
This example is perfectly safe, because the function creates scope and thus insulates it from other scripts:
<script>(function() {
var blah = function() {
alert('blah');
};
var xyz = somethingorother();
DoSomeFunkyStuff();
})();
</script>
The functions being called/defined don’t realize that they’re not in the global scope. You’ve just made a little mini-global scope for them to play in.
Or, if you have a library that takes a parameter, you can create and invoke a lamda for this:
(function(id){MyLibrary.Attach_Behavior(id);
})('my_element_id');
Yes, it’s rather odd-looking, to someone used to the C/C++/Perl/PHP mix of OOP and procedural styles. JavaScript is a lot more like LISP than it is like Java. But, unlike LISP, there’s more than one delimiter, so you don’t have stuff like:
(something (somethingelse (a list (of items) and more (items) (function arg arg2 (arg3 arg4) blah (foo bar) quuz))))))))))))))))))))))))))))))))))))I took a class on LISP in college. I was very upset that someone took such a great idea of a lamda-based language and screwed it up by giving it such aweful syntax. It’s so bad that you really can’t do much of anything practical with it.
Another option, of course, is to run your script in the window.onload handler, but if you have something that can get started right away, then it’s best to run it right away so that the user doesn’t have to wait for every darn image to download before the behavior is available.
You’re a Yahoo!, right? Ping me at isaac_schlueter if you’d like to see a proto-production example of lamdas used to attach events with onAvailable without polluting the global scope. There is a practical application of this madness, I swear :)
April 14th, 2006 at 10:51 am
Isaac, I didn’t think we were allowed to talk about onAvailable ;) I indeed know what you’re talking about. Let’s just let Matt Sweeney talk about it in our next podcast. onAvailable is definitely useful especially since users very often like to play with the page before it’s fully loaded.
April 21st, 2006 at 2:38 am
kentaromiura is right, so_what_am_i never contains a function, and is never declared a function. It simply contains the resolved value of the right hand side of the assignment, which being an immediately executed anonymous function with no return, is undefined.
June 29th, 2006 at 12:01 am
[...] Although this may look awkward at first pass, it’s what’s known as an immediate self-invoked function - and in our case, we’re returning an object at declaration-time. Unda-stood? [...]
July 5th, 2006 at 2:14 am
I like the idea of self invoked functions and have aready started using them, one question.. I’ve seen two slighty different variations:
(function() {}() ) and (function() {} )()
that is the () is either inside or outside the enclosing brackets. It doesn’t seem to make much difference either way. Does it matter?
July 20th, 2006 at 4:06 pm
/* Note: The function statement */
function membername() {
// do stuff here
}
/* is shorthand for */
var membername = function() {
// do stuff here
};
No, it’s not. Try alert(membername.name) after each call on Firefox.
Nickolay
July 20th, 2006 at 4:52 pm
@Nickolay. With that one exception, it is still a shorthand. They both become declared and how often do you call ‘.name’ on a function?
July 21st, 2006 at 10:45 pm
[...] Awkward Looking Javascript [...]
November 24th, 2007 at 2:27 am
Thanks to all for the examples. I’m boggled by some of it but I will be using self invoking functions and I just wanted to check out the different syntaxes I had to choose from.