Wait till I come! » Blog Archive » Show love to the object literal
Random notes by Chris Heilmann

Show love to the object literal

German Visitors: Zur deutschen Version gehts hier – auf dem Blog von Jens Grochtdreis

If you are just getting your teeth into JavaScript, or if you used it in the past and re-discovered it in the wake of the AJAX craze you might have been baffled by scripts that come in a new syntax.

While older copy and paste scripts looked like this:

var commonSense=null;
var standardsCompliance="50%";
function init(){
  // code
}
function doStuff(){
  // code
}
function doMoreStuff(){
  // code
}

Newer scripts inside tutorials tend to look like this:

awesome={
  commonSense:null,
  standardsCompliance:"50%",
  init:function(){
    // code
  },
  doStuff:function(){
    // code
  },
  doMoreStuff:function(){
    // code
  }
}

The new syntax is called the object literal and is pretty close to sliced bread. Here is why:

The problem with global functions and variables.

One of the biggest obstacles of JavaScripts you find in the wild is that they tend to claim the browser and variable names for themselves exclusively. If you only apply one script to your HTML document, that is not an issue, but when you use several scripts you might get into trouble.

If you check some of my older articles you will realise that I tended to use rather generic function names like init() or validate() . You might also have encountered scripts by me or other people that use global variables like selectedItem or current .

Global variables are those that are defined outside functions or inside functions without using the var keyword.

Imagine several developers had the same grand idea and you apply both scripts to your web page:

<script type="text/javascript" src="easyFameAndFortune.js"></script>
<script type="text/javascript" src="thirdPartyStuff.js"></script>

My code in easyFameAndFortune.js will not be executed at all, as the functions init() and validate() have been redefined � or you could say overwritten � by the functions with the same name in thirdPartyStuff.js. If both scripts shared a global variable named current functions in both would overwrite the value needed for the other.

It is the same phenomenon you might have encountered with several style sheets applied to the same document. You change, hack and debug in the main style sheet and wonder why nothing works until you realise that the bug is actually in a different style sheet where you or someone else applied something to the same selector you try to debug.

How to avoid the problem?

There are several solutions:

  • Don�t use generic names in your scripts (which is a shame as init and validate does what it says on the tin)
  • Add a name to each of the functions like easyFameAndFortune_init and easyFameAndFortune_validate
  • Turn the functions into methods and the variables into parameters of an object

The latter is what higher programming languages like Java, PHP or C# do, although that instead of an object, they use classes. There are no classes in JavaScript, so we will have to do with an object.

myscript=new Object();
myscript.current=1;
myscript.init=function(){
  // some code
}
myscript.validate=function(){
  // some code
}

This means that unless both scripts have the same object name (you might want to avoid calling the object init) they won�t overwrite each other. This makes the script play nicely with other scripts, but it still feels a bit cumbersome to repeat the object name every time you add a new method or variable. The solution for that is the object literal, a JavaScript syntax that has been around for quite a while but wasn�t used much in publicly available scripts. It does the same as the earlier script, but the syntax changes slightly:

myscript={
  current:1,
  init:function(){
    // code
  },
  validate:function(){
    // code 
 }
}

Instead of = signs you use : to define the parameters and methods, and instead of semicolons, you need to end each definition but the last one with a comma.
Notice, that the curly brace ending the method validate has no comma. If you were to add another method, it would need one:

myscript={
  current:1,
  init:function(){
    // code
  },
  validate:function(){
    // code 

  },

  send:function(){
    // code 
  }
}

Spread the message

Not only does the object literal ensure that your script is self contained and you don�t have to repeat the object name � it also sends a message that your script is modern and tries to stay as unobtrusive as possible.

Consider it a secret handshake between DOM scripters :-)

34 Responses to “Show love to the object literal”

  1. Jeff L Says:

    I've bookmarked this on delicious, as I feel there is some good info here that someday I'll be able to understand. :-)

  2. Matthijs Says:

    Good post Christian, thanks! Just yesterday when I was browsing some ajax/ dom /javascript scripts and libraries the question on my mind was: ok, all very nice, but what happens if I combine some of these functions and libraries? This article is bookmarked :)

  3. William Doyle Says:

    a question about parameters in the object literal notation. can you only have literals as parameters or you also have parameter values be functions like so:
    name = {

    parameter1 : document.getElementById('id');
    function1 : function() {
    code...
    }
    }

  4. Chris Heilmann Says:

    No, for the reason that they are not available when the document hasn’t loaded yet.
    If you tried to use a:

    
    bla=document.body;
    alert(bla);
    

    Outside a function called onload of the window it will also result in an error.
    If you want to assign new parameters of the main object, you can do that in a method:

    
    myStuff={
      init:function(){
        myStuff.myVariable=document.getElementById('bla');
        alert(myStuff.myVariable.innerHTML);
      }
    }
    window.onload=myStuff.init;
    

    Will work, and you’ll have the DIV as myStuff.myVariable. However, it is always a good idea to test if the DIV with the ID really exists before assigning it to a parameter.

    
    myStuff={
      init:function(){
        if(!document.getElementById('bla')){return;}
        myStuff.myVariable=document.getElementById('bla');
        alert(myStuff.myVariable.innerHTML);
      }
    }
    window.onload=myStuff.init;
    

    You can also keep the ID as a parameter, which is the option I normally choose to keep it out of the methods:

    
    myStuff={
      divID:'bla',
      init:function(){
        if(!document.getElementById(myStuff.divID)){return;}
        myStuff.myVariable=document.getElementById(myStuff.divID);
        alert(myStuff.myVariable.innerHTML);
      }
    }
    window.onload=myStuff.init;
    
  5. Sjoerd Visscher Says:

    Don’t forget the arry literal! var arr = []; instead of var arr = new Array();

  6. Simon Says:

    I hate to rain on the parade. I do love Object literals, and Array literals and all the other lovely things that don't work in IE 5.

    Unfourtunately my boss likes things to work in IE 5 because people complain if they don't. So I tend to have to use the x = new Object; x.a = blah; and so on method.

    Of course you can always go with the IE 5 gets nada method (which I've been pushing for for a while)

  7. Jordi Says:

    I do love Object literals, and Array literals and all the other lovely things that don’t work in IE 5.

    ¿Are you sure? Because I tested some scripts with Object literals on IE4, and they work beautifully.

    var obj={

    pr0n:'jdksnjk',
    n0rp:'jsadier'
    }
    alert(obj.pr0n);

    It displays what it should!

  8. Oliver Says:

    "I hate to rain on the parade. I do love Object literals, and Array literals and all the other lovely things that don’t work in IE 5."

    vs

    "Are you sure? Because I tested some scripts with Object literals on IE4, and they work beautifully."

    Presumably this'd be IE5 for the Mac - aptly described as a "buggy piece of crap" on Quirksmode.

  9. Intillium Blog » Blog Archive » Show love to the object literal Says:

    [...] w syntax is called the object literal and is pretty close to sliced bread. http://www.wait-till-i.com/index.php?p=239 Explore posts in the same categories: JavaScript [...]

  10. Stefan Gössner Says:

    Thanks for that Chris. I consider var awsome={ ... }; a slightly better coding style.

  11. Hermann Klinke Says:

    I personally hate object literal notation. The following feels more natural and it’s possible to add classes, objects and members to existing objects and namespaces:

    instance:

    var awesome = new Object();
    awesome.commonSense=null;
    awesome.standardsCompliance="50%";
    awesome.init = function (){
    // code
    }
    awesome.doStuff = function(){
    // code
    }
    awesome.doMoreStuff = function(){
    // code
    }

    class definition

    function awesome()
    {
    //constructor
    }
    awesome.prototype.commonSense=null;
    awesome.prototype.standardsCompliance="50%";
    awesome.prototype.init = function (){
    // code
    }
    awesome.prototype.doStuff = function(){
    // code
    }
    awesome.prototype.doMoreStuff = function(){
    // code
    }

    add object instance or class definition to an existing namespace, class definition or object instance

    namespace.awesome = ....
    classDefinition.awesome = ...
    objectInstance.awesome = ...

  12. Talking to myself… » Links: 2-19-2006 Says:

    [...] ox : Free your music! (categories: audio gadgets hardware home mp3 music ) Show love to the object literal – Wait till I come! (categories: javascript webdev ) Xdelt [...]

  13. Irina Says:

    I would rewrite the part below:

    init:function(){
    if(!document.getElementById('bla')){return;}
    myStuff.myVariable=document.getElementById('bla');
    alert(myStuff.myVariable.innerHTML);
    }

    like this (no need to search for 'bla' twice):

    init:function(){
    var oBla = document.getElementById('bla');
    if (oBla==undefined) {return;}
    myStuff.myVariable=oBla;
    alert(myStuff.myVariable.innerHTML);
    }

  14. Lee Kowalkowski Says:

    I like using Object Notation for most applications. However, in the past, I have favoured the following notation, perhaps due to its “evil genius” aura, usually to take advantage of private members.


    var myObject = new function()
    {
    var privateVariable = "Hello";
    this.publicVariable = "World!";

    this.getPrivateVariable = function()
    {
    return privateVariable;
    }

    this.setPrivateVariable = function(newPrivateVariable)
    {
    privateVariable = newPrivateVariable;
    }
    }

    alert(myObject.privateVariable + " " + myObject.publicVariable); // undefined World!
    alert(myObject.getPrivateVariable() + " " + myObject.publicVariable); // Hello World!

    myObject.privateVariable = "Goodbye, Cruel";

    alert(myObject.privateVariable + " " + myObject.publicVariable); // Goodbye, Cruel World!
    alert(myObject.getPrivateVariable() + " " + myObject.publicVariable); // Hello World!

    This is a nice way of achieving encapsulation, as the example shows. It’s not possible to use the private variables directly, the get and set methods must be used.

    I’ve not seen any equivalent examples using object notation though, can it be done? I’d love to become 100% converted!

  15. Tom Says:

    Good article Chris. I had noticed the same trend that you did while watching all the Ajax stuff pour in. I had begun using it a little bit (and used it more when you suggested it for my latest problem via thelist - hat tip to you) and I'm finding not only is it clean and sensible, but I like reading it better than the old way - it just seems to make more sense.

    Looks like lots of these new Ajax frameworks and Libs are using it too.

  16. Episode 04: Paul Boag Interview Says:

    [...] fore my entry was posted to this site, Chris Heilmann writes some practical advice on even more love on the object literal. Notables from this Episode SxSW whic [...]

  17. Fini Alring Says:

    I tend to use this method to create object with attributes and methods. I'm not too fond of Object Literal style, since I feel this has a more clean feel, and makes it easy to change underlying methods, without having to cut and paste source all over the place. But my biggest issue with Object Literals is the fact you need that little comma, so ugly! (not to mention har d to spot)

    /* Object constructor */
    function BioQuery( inputQuery ) {

    /* properties */
    this.queryString;
    this.queryXML;

    /* methods */
    this.tokenizer = _BioQuery_tokenizer;
    this.toTree = _BioQuery_toTree;
    this.toXML = _BioQuery_toXML;
    }

    /* implementation of the methods */
    function _BioQuery_tokenizer() {}
    function _BioQuery_toTree() {}
    function _BioQuery_toXML() {}

    /* Init object instance */
    var bq = new BioQuery('test');

  18. Quick Explanation of the Object Literal - The Web Standards Project Says:

    [...] ’, init:function(){ }, doStuff:function(){ } } It hopefully will help you to read Show love to the object literal.

    Your Replies No comments have been made. [...]

  19. Object-Oriented Concepts - Nefarious Designs, Web Standards Design and Development, East Grinstead, West Sussex, UK Says:

    [...] capable web developers. This can be best illustrated by the recent boom of interest in the Javascript object literal. As Senior Web Developer at Rentokil, I am required to be technical lead wit [...]

  20. Object-Oriented Javascript - Nefarious Designs, Web Standards Design and Development, East Grinstead, West Sussex, UK Says:

    [...] more information on the object literal, I recommend reading Chris Heilmann’s “Show Love to The Object Literal,” and Dustin Diaz’s “JSON for the Masses.” Fan [...]

  21. La X di JSON - prima parte | Central Scrutinizer - [ il web in 283 comode rate ] Says:

    [...] che lavorano in cooperazione. (Esempi a proposito sono segnalati nei post di Dustin Diaz e Chris Heilmann sull’argomento). Nel 2002 il developer D [...]

  22. nothing happens Says:

    [...] lar among JavaScript coders in recent years with the AJAX craze. Thus today I came across this blog post on the subject, which prompted me to think about the object literal, which I’ve o [...]

  23. chuck Says:

    This post really got me thinking. I work with Flash, and ActionScript is basically the same language as JavaScript, so it, too, has the object literal. Not to link-whore, but I've written a post myself on how pretty much this exact same use of the object literal would really clear up a lot of code I've seen.

  24. Michael Says:

    Check out Ajile. It’s an excellent approach to namespaces (code organization) in JavaScript.

  25. Promoting the responsible use of JavaScript: writing, teaching and presenting - The Web Standards Project Says:

    [...] and James Edwards’ “The JavaScript Anthology” Articles Chris Heilmann: Show your love to the object literal Chris Heilmann: From DHTML to DOM Scripting Aaron Gustafson: Gett [...]

  26. Script Artists » Archiv » Sinnvolle Nutzung von JavaScript Says:

    [...] logy” unter der technischen Leitung von Derek Featherstone Artikel Chris Heilmann: Show your love to the object literal Chris Heilmann: From DHTML to DOM Scripting Aaron Gustafson: Gett [...]

  27. Vitamin Features » The Importance of Maintainable JavaScript Says:

    [...] can keep scripts self-contained by namespacing them or wrapping them in an object via the object literal. You ensure you don’t hijack variables by keeping them in scope of your functions [...]

  28. IONCANNON » Good article on keeping javascript maintainable Says:

    [...] ble to any code. The important parts of the article cover javascript specific things like: object literals, namespa [...]

  29. Merth Says:

    Hi Chris, awesome article. But i am having issues with object scope i think.

    MyObject = {
    objectProperty:"HELLO",

    applyAction : function(item) {
    item.onmouseover = this.doOver;
    },

    doOver : function() {
    alert(objectProperty);
    }
    }

    all i get in alert window is "undefined". How can i make javscript to alert objectProperty without assigning objectProperty to a global variable?

    Answer: alert(MyObject.objectProperty);

  30. Merth Says:

    thanks, but what if i have 2 instances of that object at the same time?

  31. » Del literal de objeto - Scriptia Says:

    [...] hashes, permite mantener el código limpio y bien ordenadito. Chris Heilmann lo explica en Show lov to the object literal. Etiquetas objetos, l [...]

  32. The English Guy » Tactile & Braille Signs, Online Ordering Says:

    [...] ity, baby changing etc., I should mention here that this is a DOM-compliant page utilising object literal notation JavaScript code. I wanted to test it out to see if there were any problems, or [...]

  33. Alex Says:

    Bit late but in case anyone has the same thing as Merth, the line you’ll need is:
    Answer: alert(<em>this</em>.objectProperty);

    That’ll reference the current instance of the object in case you’ve got multiples.

  34. Michael Prescott Says:

    I recently stumbled upon some usage of Object Literals and found your site while trying to learn why. I still don't understand why object literals are better than using prototype.