with Imagination: by Dustin Diaz

./with Imagination

A JavaScript, CSS, XHTML web log focusing on usability and accessibility by Dustin Diaz

Awkard Looking JavaScript

Wednesday, April 12th, 2006

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.

20 Responses to “Awkard Looking JavaScript”

  1. Quentin

    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);

  2. Rian Orie

    .. 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..

  3. Simon Willison

    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).

  4. Justin Perkins

    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();
    }())

  5. Dustin Diaz

    aaaaaaAAAAAAAHHHHH!
    *runs in circles*

  6. Stephen Clay

    So what’s the practical difference between these?

    var membername = function() {};

    var membername = function membername() {};

    var membername = function differentname() {};

  7. Vincenzo

    I just found another way of calling anonymous functions:
    void function(me) {
    alert(me);
    }(’huzzah’);

  8. Jim

    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?

  9. Brian LePore

    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.

    I think the reason you can’t call ‘who_am_i’ is because you never declared it.

  10. kentaromiura

    …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”)
    }

  11. Dustin Diaz

    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_i function, 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 :)

  12. Isaac Z. Schlueter

    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 :)

  13. Dustin Diaz

    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.

  14. ep

    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.

  15. How to achieve private, public, and privileged members in JavaScript

    […] 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? […]

  16. Pete Boere

    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?

  17. Nickolay Ponomarev

    /* 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

  18. Dustin Diaz

    @Nickolay. With that one exception, it is still a shorthand. They both become declared and how often do you call ‘.name’ on a function?

  19. EstadoBeta » Archivo » Funciones autoejecutables en Javascript

    […] Awkward Looking Javascript […]

  20. Ffoeg

    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.

Leave a Reply

Phone Number:

If you're about to post code in your comment, please wrap your code with the tag-combo <pre><code>. Also please escape your html entities - otherwise they will be stripped out. I recommend using postable.

Get "JavaScript Design Patterns"

"As a web developer, you'll already know that JavaScript™ is a powerful language, allowing you to add an impressive array of dynamic functionality to otherwise static web sites. But there is more power waiting to be unlocked--JavaScript is capable of full object-oriented capabilities, and by applying OOP principles, best practices, and design patterns to your code, you can make it more powerful, more efficient, and easier to work with alone or as part of a team."

Buy JS Design Patterns from Amazon.com Buy JS Design Patterns from Apress

Flickr

Submit a Prototype

All content copyright © 2003 - 2007 under the Creative Commons License. Wanna know something? Just ask.

About | Archives | Blog Search

[x] close

Loading...

Submit a prototype

By checking this prototype I agree that I am not submitting false credentials, pornography, or a hate crime website. I also understand that by submitting my entry I may or may not be accepted, and if accepted, my entry may be taken down at any given time if I violate these terms.