Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Does the fact that anonymous self-referencing function closures are so prevelant in JavaScript suggest that JavaScript is an incomplete specification? We see so much of this:

(function () { /* do cool stuff */ })();

and I suppose everything is a matter of taste, but does this not look like a kludge, when all you want is a private namespace? Couldn't JavaScript implement packages and proper classes?

Compare to ActionScript 3, also based on ECMAScript, where you get

package com.tomauger {
  import bar;
  class Foo {
     public function Foo(){
       // etc...
     }

     public function show(){
       // show stuff
     }

     public function hide(){
       // hide stuff
     }
     // etc...
  }
}

Contrast to the convolutions we perform in JavaScript (this, from the jQuery plugin authoring documentation):

(function( $ ){

  var methods = {
    init : function( options ) { // THIS },
    show : function( ) { // IS   },
    hide : function( ) { // GOOD },
    update : function( content ) { // !!! }
  };

  $.fn.tooltip = function( method ) {

    // Method calling logic
    if ( methods[method] ) {
      return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'Method ' +  method + ' does not exist on jQuery.tooltip' );
    }    

  };

})( jQuery );

I appreciate that this question could easily degenerate into a rant about preferences and programming styles, but I'm actually very curious to hear how you seasoned programmers feel about this and whether it feels natural, like learning different idiosyncrasies of a new language, or kludgy, like a workaround to some basic programming language components that are just not implemented?

share|improve this question
21  
"Couldn't JavaScript implement ... proper classes?" No. It already has proper prototypes. Prototypes are not inferior to classes. They are different. People have tried adding classes to JavaScript at various times and have been rather unsuccessful. –  Rein Henrichs May 26 '11 at 21:11
5  
@Rein: And yet somehow ActionScript managed it... –  Mason Wheeler May 26 '11 at 21:27
6  
@Tom there aren't "built-in classes". There's no such thing as a class in a prototypal language. You keep conflating the two paradigms. –  Rein Henrichs May 26 '11 at 22:07
1  
I personally find the anonymous function language feature more flexible than classes. However I do like functional programming in which this idiom is common. –  dietbuddha May 27 '11 at 2:38
1  
For others, here: brianodell.net/?page_id=516 is an awesome primer on JavaScript as a prototypal language. –  Tom Auger Jun 15 '11 at 16:59
show 7 more comments

6 Answers

I suppose everything is a matter of taste, but does this not look like a kludge, when all you want is a private namespace? Couldn't JavaScript implement packages and proper classes?

Most of the comments are argue against the myth that "prototypes are poor man's classes", so I'll just repeat that prototype-based OO isn't inferior in any way to class-based OO.

The other point "a kludge when all you want it a private namespace". You might be surprised to know that Scheme uses the exact same kludge to define scopes. That didn't stop from becoming the archetypal example of lexical scoping well done.

Of course, in Scheme, the 'kludge' is hidden behind macros....

share|improve this answer
1  
You present no evidence to back up your assertion that Scheme is the primary example of lexical scoping well-done, or that this had anything to do with how Scheme used functions to define scopes. –  DeadMG Feb 13 '13 at 14:22
    
Can't speak to Scheme being an exemplar but one example of JS co-creator Brendan Eich discussing Scheme playing a role in JS's design here: readwrite.com/2011/07/22/javascript-was-no-accident –  Erik Reppen Feb 13 '13 at 15:34
add comment

The other thing you are missing is that javscript must be backwards compatible. If you try to introduce package syntax it could really break the web in some crazy ways. That would be bad! Doug Crockford has talked about this at various points and why the attempts to add it have failed.

share|improve this answer
    
That's a good point. And yet ActionScript managed it, by simply putting out a new version. When defining you script tag, you've always been able to specify JavaScript version, so "breaking" existing sites should be a non-issue. –  Tom Auger May 27 '11 at 13:09
1  
In practice most script tags on the net do not have a version number. To be honest I'm not sure of all the issues on this one, but I do know that the folks that think about this stuff have decided that it is not doable. –  Zachary K May 27 '11 at 14:12
1  
@Tom: Adobe also has full control over the Flash platform. No one entity has full control over all the JS platforms out there. Also, simply tacking on a version number for a JS script in a browser would mean you either are not supporting older browsers or have to write two scripts. So, it is an issue. –  Jeremy Heiler May 31 '11 at 14:20
add comment

First off, a couple things:

  1. Another way of looking at JavaScript is the 1 million and 1 things you can do with the function as a construct. It's all there if you look for it. It's just never far from a function.

  2. That jQuery plug-in authoring thing is awful. I have no idea why they're advocating that. $ extensions should be general-use stuff that $ already has pretty-well covered not build-me-a-complete-widget methods. It's a DOM-API normalization tool. It's use is best buried inside your own objects. I don't see the appeal of using it as a full-on UI library repository.

Packages on the Client Side Web are Pointless

What I don't personally like about packages on the client-side web is that we'd basically be pretending we're doing something that we're really not. In a post .NET webforms and gobs-of-horrifying-stuff-that-never-panned-out-from-our-Java-friends world, I'd rather think of a hunk of HTML with linked resources as what it really is and not try to appease learning-new-things-resistant OS app developers by pretending it's something else. In JS on the client-side web, nothing gets "imported" barring doing something awful with Ajax that operates in ignorance of browser-caching, which yes, many have tried to do. All that matters to the browser is that it was either loaded in and interpreted or it wasn't. We don't have more code stashed on the client somewhere available for use "just in case" for good reasons. #1 being that I just described a plug-in and browser plug-in dependencies for web apps as a phenomenon has not generally worked out too well. We want web now. Not after Adobe or Sun is done updating the third time this week.

The Language Has What it Needs for Structure

JS objects are highly mutable. We can have branching trees of namespaces to any degree that we find it useful to do so and it's very easy to do. But yes, for anything re-usable you do have to stick the root of any library at the global space. All dependencies are linked and loaded at the same time anyway, so what's the point of doing anything else? The point of avoiding the global namespace isn't that anything there is bad. It's that too much stuff there is bad because you run the risk of namespace collisions or accidentally overwriting core language features.

Just Because it's Popular Doesn't Mean We're Doing it Right

Now when you see this all over a client-side web app:

(function(){
//lots of functions defined and fired and statement code here
})()

The problem isn't that we lack tools to structure an app around, the problem is that people aren't valuing structure. For 2-3 page one-off temporary throwaway sites at a design agency, I don't really have a problem with that. Where it gets ugly is when you have to build something maintainable and legible and easy to modify.

But when you get to the place where it's time to just implement all of the re-usable objects and factories and maybe one or two new temporary vars might creep into that process, it's a convenience.

But There Are Implementations of JS With Packages/Modules

Keep in mind that in Node.js, where such things make a lot more sense, they do have modules. JS, assuming we can avoid uber-config-hell that plagues other languages, is the only thing in the equation and each executed file is its own isolated scope. But on a web page, linking a js-file is itself the import statement. Doing more imports on the fly is just a waste of time and resources since getting the resources requires a lot more effort than simply adding links to files as you need them knowing they'll be cached in a browser if another page needs them again. So is trying to split up the global space by doing anything other than create adapter object factories like jQuery or more traditional objects that cover a large subset of tasks in a given domain while occupying one spot in global. There's also efforts underway to actually write modules into future spec: http://wiki.ecmascript.org/doku.php?id=harmony:modules

So no, there's nothing wrong with auto-invokers used to avoid global namespace pollution when there's a good reason to use such things (more often than not there isn't). And we have persistent private-equivalent properties in our objects (just define a var in the constructor and don't expose it as a property).

The fact that we CAN do such things, however, is awesome. Heavy usage is a sign that JS developers are still maturing perhaps, but it's not a gaping hole in the language to anybody who's not trying to force a paradigm into the client-side web that just doesn't make sense here.

share|improve this answer
    
To the Down-Voter, could you please explain why? When someone writes that much I think he deserves an explanation! –  Songo Feb 13 '13 at 15:05
    
+1 good answer, not sure why the down vote before. –  pllee Feb 13 '13 at 17:21
    
Awesome write-up and great perspective. I also like the "just because it's a trope doesn't mean it's right.". I think my issue is that I'm more comfortable with stricter languages, which (IMO) helps development efficiency in a number of ways. JavaScript seems really wishy-washy with not a lot of built in checks and balances: you can do whatever you want, hence the landscape out there is a mess of idioms and practices. It's hard to nail down the "right" way to approach your coding structure. Though I agree that for quick 1-off jobbies, this is not a big concern. –  Tom Auger Feb 14 '13 at 15:12
    
IMO, there's a lot of things you can do with plenty of rope other than hang yourself and you learn to write robust code faster from occasional self-hangings which happen less-frequently as you develop better habits, but I won't pretend it's for everyone or an ideal candidate for every job. I suspect the more you learn about it, however, the more tolerable you'll find it. I feel like I'm missing half my brain when trying to do things in languages without first class functions or objects as flexible/mutable as JS's. –  Erik Reppen Feb 14 '13 at 18:58
add comment

Yes, it is a kludge.

A lot of people are saying that "prototypes are not inferior to classes". I disagree, but that's a matter of preference. But that's not even the real problem with JavaScript - the problem is that it was originally designed as a quick-and-dirty scripting language for making things like animated buttons. Back in the mid-90s nobody ever thought that JavaScript would be asked to do some of the crazy stuff that it's doing now.

share|improve this answer
5  
I disagree, JavaScript the language is actually really awesome. That it was lumped together with an under specified and mutually-incompatible DOM is where all the problems started. –  Dean Harding May 27 '11 at 9:06
1  
What does this have to do with prototypes? –  Erik Reppen Feb 13 '13 at 13:14
add comment

Anonymous self-invoking functions are more akin to modules than to classes. It is annoying that the default for javascript is to run in the global scope. The committee working on JS.next is seriously considering adding modules, so that you don't drop your local variables into the global scope. Luckily, Javascript's functions have such convenient semantics that we can use an anonymous function as a private scope with relative ease.

I don't see how classes really enter in to the discussion at all, except that they are the top-level scoping construct in many languages. A better module/package/please-give-me-a-local-scope-so-i-don't-leave-my-variables-in-the-global-environment construct would be very nice to have.

share|improve this answer
add comment

You might want to take a look at ExtJS 3 and 4 where they have managed to implement namespaces quite well.

-- added after -1

My point here was, it is possible to hide all these 'convolutions' and still have pretty friendly code like so:

Ext.ns('com.tomauger');
Ext.Loader.load('bar.js'); //unfortunately filname needs to be used
MyNameSpace.Foo = {
   //...
}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.