JavaScript: Curly braces are not the problem

January 15, 2010

JavaScript has picked up lots of pythonisms over the last few years which is obvioulsy a Good Thing(tm). Aza Raskin of Mozilla has now created Pyscript, a version of JavaScript sans curly braces. As a fellow Pythonista I too find curly braces aesthetically unpleasant. But I don’t think it’s the pressing issue. At the end of his post, Aza asks “What other ways can we make Javascript syntax prettier and more readable?” Let me tell you by pointing to the elephant in the room.

Writing a class/object in JavaScript, especially “subclassing,” weirds me out.

I just can’t make my peace with the functions-implicitly-become-object-constructors idea. I can see how it might make sense in a prototype world. But once you use functions to define objects, you must use the new operator for instantiation. This means there are some functions you call right away and some you don’t. I just don’t understand why it would be so bad to have a new language construct for defining objects?

The lack of such a one-and-only language construct leads to a plethora of ways how to define object methods. Some like doing it this way:

function MyObject() {
  /* constructor here */
  this.aMethod = function() {
    /* method here */
  }
}

while others like to monkey-patch them in, like so:

function MyObject() {
  /* constructor here */
}
MyObject.prototype.aMethod = function() {
  /* method here */
}

or even:

MyObject.prototype = {
  aMethod: function() {
    /* method here */
  }
}

I’m sorry, that’s just too many ways for doing something all too common in object-oriented languages: defining objects. Not to mention the prototype-less one:

var MyObject = {
  aMethod: function() {
    /* method here */
  }
}

(Of course, when using Mozilla’s JavaScript engine you can also monkey patch a prototype into this via MyObject.__proto__ = {...}. In fact, the Mozilla folks like using __proto__ all the time to specify the object’s baseclass, uh, I mean baseprototype.)

I know what you’re going to say now. People could just settle for one way and impose that as a coding convention. But why hasn’t that happened? My suspicion is that because none of the choices are truly great. The language itself doesn’t encourage a particular choice more than any other, and that’s bad. Arbitration like that is just one step away from Perl.

Coming back to Aza’s Pyscript, I think it’s a useful exercise because it shows how much you can improve JavaScript with just a few lines of, uh, JavaScript. Perhaps I should give it a whirl and come up with a language construct for creating prototype-based objects, including a decent inheritance syntax. What do you think that should look like?

Update: I’ve written a follow-up post that contains a solution.

16 Responses to “JavaScript: Curly braces are not the problem”


  1. I get confused every time I try to do something “object oriented” in JavaScript. I know I don’t fully understand the language and its idioms, since I never learned it “properly”. It does weird me out though, being so different from obvious comparisons such as, erm, Java. Or C. Or Python. Or Perl. Or Ruby. Or any other language you may use on the server side.

    +1 to a class keyword.🙂

    • philikon Says:

      I sympathise with your point on some level, but I’m not sure that adding classes to JavaScript is a good idea. Because the next thing people are going to want is interfaces, private/public/protected properties etc. and you’ll end up with something like Java. This is the route ES4 has taken and I’m not sure I like it.

      Despite being the shitty little language that it is, JavaScript has enabled hundreds of thousands of brilliant web applications. And the majority weren’t written in Java first and then translated to JS (hear that, Google). I think web applications have been successful *because* JS is such a constrained language, not despite of it. Especially since there are half a dozen implementations of it out there in the wild.


      • I don’t buy that. I’d like a more normal way to do OOP. I don’t need public/private methods or interfaces any more than I do in Python. But your post adequately describes that few people understand how to package up related functionality into objects and avoid polluting the global namespace. All of the options you outline look like hacks that use language features for things they weren’t originally designed for (otherwise, they wouldn’t have called the fundamental keyword ‘function’).

      • rgz Says:

        @Martin Aspeli
        That’s called orthogonaloty, and its a plus.

        Adding functions to objects is a nice feature and with that you don’t need separate method syntax.

  2. sOKzZuKa Says:

    The syntax is there (almost) in ES4 specyfication implemented in Adobe ActionScript3

  3. damien Says:

    The second one is just monkey patching; The last one creates an object not class.

    The first and third ones are complementary. Since it’s inefficient, you should only use the first one if you need to keep a reference to the instance using closure (or if you need private variables). It’s possible to do the same in Python but It is useless because self is always bound to the instance.

  4. rgz Says:

    Actually the monkey patching way is the only correct way to do it.

    The all in the constructor wastes CPU cycles and ram, creating and recreating identical functions/methods for each instance.

    The third example, setting the prototype to a new object with methods overwrites the prior prototype which is fine only when you are NOT inheriting.

    Monkey patching works always, so that’s what you should always use.

    I myself use the prototype-less approach all the time however.

    • philikon Says:

      damien and rgz,

      I was vaguely aware of the semantic differences, so thanks for making it crystal clear. Still, the fact that they these differences exist and developers still seem to use the variations interchangingly makes my point even stronger.

    • vol7ron Says:

      I concur: The “monkey patching”, as you so call it, is actually the way that this should be completed.
      The function or variable (whatever is prototyped) will only be created once in memory, rather than each time that object is created. Therefore, what are considered static globals, should be prototyped.

      Here’s a decent approach to OOP in Javascript: http://mckoss.com/jscript/object.htm

      Mozilla may have developed “Pyscript”, but as with any Javascript package, it is built around a core Javascript file that converts your script into Javascript. There is a performance impact for this conversion.

      The question is if the cleaner code is worth the performance impact. In my opinion, I would say no. In addition to performance there are other things you have to watch out for: you have to make sure the core package is updated with Javascript updates, you have to be assure the package has no bugs in it, you have to make sure the package is secure (and source is trustworthy).

      There are too many things that you need to question – is fewer curly braces really worth it?

  5. Henrique Says:

    I would prefer… not have to code in Javascript.

    Really, it’s only being used because it’s what’s being shipped everywhere since the browser wars. It’s not a great language for anything, not even to work with the DOM. Proof of that is the amount of frameworks out there trying to make JS suck less at this.

    On the pro side, it’s a well sandboxed language, but that’s it. All the cons outweight: uses a weird inheritance model; no namespaces, rendering the use of 3rd party code a russian roulette; lousy types; the whole API, specially the part dedicated for traversing the DOM, sucks balls; events are messy; AJAX is a hack… bah, I could go on.

    The fact is, by shipping JS and *only* JS on every browser for more than a decade, now we face complete lethargy on improvement of web client-side scripting, basing everything on hacks. No wonder why web development sucks so much still.

    Looking forward for a day when browsers would accept client-side code AND interpreters/VMs at will, so a site could provide it’s own framework, similar to how a Mac app provides its own framework in a bundle.

    • philikon Says:

      I’m not going to get into a JS flame war because that won’t lead anywhere, and it’s not very constructive.🙂

      Let me just say this about your last point: Aza’s Pyscript sort of demonstrates — on a small scale of course — that bundling your website with your own client-side “language” works already. At least that, if nothing else, is what I take home from it (see my last paragraph)

  6. damien Says:

    @Henrique: There are more Python framework… and they usually only target one Python implementation😉

  7. philikon Says:

    I’ve been pondering this for a few days now. Despite the fact that the third option is a more concise spelling (because you define all the methods in one go), I think I prefer the second way:

      MyObject.prototype.aMethod = function() {...}

    Even though that one reminds me of C++ where you define methods outside the class body. I think the main reason I don’t like the third spelling is that

      aMethod: function() {...}

    simply isn’t very pleasing to my eyes. I think something like

      prototype MyObject {
          extends new BaseObject();
    
          function MyObject() {
              /* constructor here */
          }
    
          function aMethod() {
              /* method here */
          }
      }

    might work for me. It would be syntactic sugar for

      function MyObject() {
          /* constructor here */
      }
      MyObject.prototype = new BaseObject();
    
      MyObject.prototype.aMethod = function() {
          /* a method */
      }
  8. infinite8s Says:

    Javascript is basically a scheme variant with C-syntax. The reason there are so many ways of doing object-orientation is that prototype languages are more general than object oriented languages, and there are a variety of different ways you might want to do object orientation. It might seem weird if you come from a Java/C background, since these languages use the canonical object-orientation. Doug Crockford gives a really good talk about the good parts of javascript: http://googlecode.blogspot.com/2009/03/doug-crockford-javascript-good-parts.html

    • philikon Says:

      Thanks for that link, that’s a really nice talk. It makes you appreciate some of JavaScript’s unique features even more. I especially like how he talks about the attitude that most people have towards JavaScript (including himself at one point apparently) and how it’s often irrational and prejudiced.

      My favourite quote: “You might be wondering, why am I betting my career on this piece of crap?”


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: