with Imagination: by Dustin Diaz

./with Imagination

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

JSON for the masses

Sunday, February 19th, 2006

Your co-workers will love you for writing in JSON because it will most likely not conflict with their scripts that are being called within the same web documents.

For Many Years…

JavaScript has been portrayed as a very ugly language. It’s been abused, misunderstood, and kicked around like the poor step-child as known in fairytales. That’s all going to end this year. As many know, Stuart Langridge proclaimed that 2005 would be the year of the DOM. He was in fact…correct. 2006 will be the year of Object Notation.

Libraries like prototype, script.aculo.us, behavior, and Rico have all made their debut in 2005 and topping the charts of development circles as some of the greatest things to happen for web developers. JavaScript is back and it’s cooler than ever! Web 2.0 is in the air (whatever that means) and innovation is at its peak (Hey, even Zeldman says we’re at web 3.0). Anyone with a D.O.M. wants to script it too. It’s in, it’s popular, and it’s only getting better.

Why?

Because JSON is here. And not only is it here, but it’s been to college and graduated here. Being part of the ECMA Standard of 1999, and then popularized by Douglas Crockford in 2002 (sort of), Object Notation has quite a history. And although that history has been ignored for quite some time, that does not excuse its unpopularity for so many years. It’s time to get with it and develop your JavaScript in Object Notation.

Reasons for JSON

  • JSON is easy. No really. It’s so easy, it’ll make you sick.
  • If you’re familiar with writing classes in PHP, then you’ll most definitely be comfortable with writing JavaScript in Object Notation
  • JSON is nothing more than name : value pairs assigned within an object.
  • JSON is easy to understand because if written well, it’s a self-documenting structure.
  • JSON is fast!
  • JSON organizes the ugly mess of procedural programming. Imagine having more than one init function.
  • You can impress your friends with JSON because it’s pretty looking
  • Your co-workers will love you for writing in JSON because it will most likely not conflict with their scripts that are being called within the same web documents.

No more fuss of writing function after function that has no meaning to which other group of functions it belongs to

What is Object Notation in JavaScript?

According to Douglas Corckford’s website, JSON is a lightweight data-interchange format. It is easy for humans to read and write… JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others.

As a simple example, Object Notation can be expressed in the following format:

Sample Object Notation Reference

var obj = {
	// string
	a : 'sampleValue',
	// array
	b : [obj1,obj2,'three',4,obj5],
	// function
	c : function() {
		var bang = this.a;
	}
}

In the above example, a, b, and c are the names, and their values are expressed immediately following the colon up until the following name (excluding the final value - in which the value just goes until the end of the object). Each pair is considered a member.

Names

Names can be anything except one of the JavaScript reserved keywords - which come to find out can actually be quite lengthy. Names also follow a few syntax rules which include not being allowed to start with a number; the entire name may not include any special characters except an underscore or dollar sign; and it cannot be a duplicate of a previously used name within the same object.

Values

Values can be expressed as a string, number, object, array, boolean (true,false), or null. To see a full explanation of the syntax rules, see Douglas’ JSON Website.

So what’s the good news?

Part of the reason JSON is so easy is that it is easy to read (for humans and programs (think parsing)). No more fuss of writing function after function that has no meaning to which other group of functions it belongs to. The fact of the matter is that programming with objects allows you as a developer to separate functions into subsets that will allow you to organize your scripts that won’t clash with one another. And although the big hoo-haa on JSON right now is that it’s a light-weight data-exchange format that multiple languages can easily understand - it simply makes sense just to use it on a structual level - even if you aren’t exchanging data.

programming with objects allows you as a developer to separate functions into subsets that will allow you to organize your scripts that won’t clash with one another

Object Notation will improve your health

If anyone has read anything by Sitepoint’s Harry Fuecks, you’ll know that Object Oriented Programming will save your life. It keeps the hair on your head and a sane mind to live in harmony with other people of this earth. It just makes sense. So if anything, take his word for it, this is where you want to be.

Better Organization

Imagine this. You’ve been asked to help out on a relatively large-scale web development project to help make it “web 2.0″ compliant (sounds cheezy, but let’s not give the marketing department too many more ideas). The project has already been worked on for roughly a month as a few things have already been written and done. The website architecture is laid out before and you quickly notice a few lines of JavaScript. Turns out it’s just some pop-up window function. No big deal. You also notice a few more lines that add a few functions to be fired upon the window ‘load’ event. With that in mind you scroll a bit back up the document and also find a few references to some external JavaScript files located appropriately in the /js/ directory. One called common.js, another preferences.js, and yet another effects.js.

At this point you begin to sulk into your chair just knowing that you’re going to be spending the day just figuring out what’s going here. Not exactly an ideal situation. Also keep in mind that nobody is aware of the benefits of writing in Object Notation. So this is going to get tedious real fast.

Getting back to the story, your task according your project manager (whomever that may be) is to add some behavior to the sidebar, something fancy, and then maybe spruce up the navigation menu with some indicators…or something like that (you’re not really sure). Brushing off what you may have found earlier, you decide to fire up a new document and call it scripts.js, then immidiately you begin hacking away to fulfill your duty as a web 2.0 developer (someone bring me back to reality when this is over).

Come Runtime, Problems arise

The day goes by and you’re satisified with your newly developed set of functions. It was all tested on localhost and works to a tee. In other words, it’s perfect.

The next day you decide it’s time to implement your new set of functions into the existing web documents… and that’s when it happens.

It turns out you’re not the only one that likes to use function names like init, run, and wrap. Without a doubt, I too have the InitRunWrap fever - so you’re not alone.

A 2006 Proposal

The following graph is a representation of what the typical common.js file looks like.

Common JavaScript for JSON

Albeit the confusion between objects and global variables, the distinction between the two should be that variables will now sit within the objects to which they pertain to. This is called scoping.

How scoping helps us

For anyone familiar with other O.O. languages - like Java or PHP, you may already be familiar with scoping. Scoping allows us to avoid clashing. Previously in our brief story about the JavaScript developer that named his/her functions with name’s like init, run, and wrap, this could have all been avoided had the previous developer scoped their functions within their own objects. If that had happened, then all we would have to worry about is not to use the same object name’s… which would probably be far more easier to avoid.

JSON is easier to read, maintain, and provides better organization

Functional vs Classy

When I’m writing JavaScript, I typically like to think that there’s two ways I can go about developing. Functional, and Classy. Functional being the standard procedure we’ve been doing for years, and Classy being that of which is written in Object Notation. And although both will get the job done - I tend to go for the classy route not only because I like to show off, but because it’s easier to read, maintain, and provides better organization.

Functional works

There’s nothing wrong it. Even some of the greatest developers in the world still do it. But there’s something inherently wrong with it. Let’s take for example a make-believe JavaScript behavior that requires use of more than a handful of functions.

Related Group of Functions

var a = '';
var b = null;
var c = document.getElementById('c');
function init() {
	// ...
}
function doThis() {
	// ...
}
function doThat() {
	// ...
}
function tweakThis() {
	// ...
}
function runThat() {
	// ...
}
function wrapThis() {
	// ...
}
function stringifyThat() {
	// ...
}
function calculateThis() {
	// ...
}
window.onload = init;

(On Functional Programming) The role of a function becomes globalized and yet becomes vague as to what its purpose is. Give it scope, then we’re in business

No doubt we can fill in the gaps as to what this possibly might mean. The problem is that this may be okay for some small project where you’re the developer and the boss, but for any project of a respectably large size, you’ll find out that this is going to cause problems fast.

And not only that, but think of the issues that will arise when you want to add extra behavior on top of this. Not only can name’s begin to clash, but it will get confusing as to what function’s belong to which group. The role of a function becomes globalized and yet becomes vague as to what its purpose is. Give it scope, then we’re in business

JSON: A Class Action

Let’s rewrite our make-believe functions into Object Notation and compare the differences.

Grouping Functions in an Object

var behavior = {
	a : '',
	b : null,
	c : Object,
	init : function() {
		// ...
		this.c = document.getElementById('c');
	},
	doThis : function() {
		// ...
	},
	doThat : function() {
		// ...
	},
	tweakThis : function() {
		// ...
	}
}
var behavior2 = {
	runThat : function() {
		// ...
	},
	wrapThis : function() {
		// ...
	},
	stringifyThat : function() {
		// ...
	},
	calculateThis : function() {
		// ...
	}
}

As you might be able to tell, we’ve now given our set of variables and functions scope! The greatest part about this was that it was so easy. By giving our set of functions a name (behavior & behavior2) and swapping our function name’s into name/value pairs which become members of their parent objects, we’ve now experienced the beauty of Object Notation.

You may also notice its terrible resemblance of PHP classes where behavior and behavior2 are classes, and the functions within them are the methods respectibly

The Noticable Differences

First of all, had we not rewritten these set of functions into methods of objects, you may have never known that they were in fact, two different sets of behaviors meant for something completely different from one another. For example, init, doThis, doThat and tweakThis are all part of the behavior object. And runThat, wrapThis, stringifyThat and calculateThis are part of the behavior2 object. Both of which may very well be doing two very different things. With that in mind, we can see now that global functionalism (yea, I made that up) is bad.

Another difference we may see is that we have now gained the pleasures and benefits of Object Oriented structures. And by that, I mean this

Low and behold: The power of this

this is a keyword often used in Object Oriented languages that help generify (now I’m just making words) naming conventions. In the cases of both behavior objects, if we were to reference this inside any one of its child methods, it would be corresponding to its most outer parent object.

For instance, in the behavior object, the first three members are set to an empty string, null, and Object. Inside the init() method, we had set the member ‘c’ by referencing it as this.c. And from that point on, we can continue to reference ‘c’ throughout the entire object simply by using the keyword this. Really, it’s that simple.

Careful how you use this

Just when you think you’ve got things down, there’s only one caveat that often goes overlooked when using the this keyword in Object structures. Always take special note on where you’re calling this from. Consider the following piece of code:

Carefulness with this

var jack = {
	a : Object,
	init : function() {
		this.a = document.getElementById('jane');
		this.a.addEventListener('click',this.alerter,false);
		this.run();
	},
	run : function() {
		this.alerter();
	},
	alerter : function() {
		alert(this.id);
	}
}
function pageLoader() {
	jack.init();
}
window.addEventListener('load',pageLoader,false);

If you take special notice, you’ll see the method alerter is being run from both an eventListener, and from the run method. If you were to access a page with this code on it, you would see an alert upon the window ‘load’ event that would read as ‘undefined‘ - but when fired upon the ‘click’ event from a link with the id of ‘jane’, we would indeed see an alert that read as ‘jane‘.

An Object Template

When developing new scripts, I often like to refer to a forumla that helps me stay organized and keep my code clean. Aside from it being unobtrusive (as coined by Stuart Langridge in Sitepoint’s DHTML Utopia) it’s what I call an Object Template. No, Object templates aren’t real things and they surely aren’t part of the D.O.M., but it is more or less of a way of creating a generic Object set up that will hold my page architecture. It looks like this:

My Object Template

var obj = {
	a : Object,
	b : Array,
	c : false,
	d : null,
	init : function() {
		// set local object vars here
		this.run();
	},
	run : function() {
		// run bulk of behavior here
	}
}
function initializer() {
	obj.init();
	// other init() methods go here
}
addEvent(window,'load',inializer);

Assuming you have an addEvent() function handy, this is a simple way to get things started. You’ll notice at the bottom the inializer which fires upon the window ‘load’ event which will in return fire any init() methods we have from different Objects. Then within the ‘obj’ Object literal, there’s a, b, c, and d which all represent possible values for these name value pairs.

The init() method itself I most typically like to use it to set up the object setting things like this.whatever, and then at the end, it runs the objects bulk of the behavior through the run() method.

Great what do I do with all this knowledge

Practice it. Learn it. Re-read it. Tell me what you think! JSON is not only for the pro’s, it’s for the masses!

145 Responses to “JSON for the masses”

  1. Johan

    I used this scrollerscript once for a project:

    Here is a part of it - is this good coding practise:

    // edited by author

  2. Jim A.

    Wow Dustin–that’s quite a long read! I am about half way thorugh but will have to come back to finish later.

    Just wanted to say that you showed my JSON about 6 months ago and I think it is fantastic. I am still making the change over when writing short quick things, but on any of the libraries I write, or large projects I work on, I am trying to remember to use it.

    Jim

  3. P.J. Onori

    It is indeed true that OOP will change your life. Ever since I moved to classes in Actionscript, it made my life easier than I could imagine.

    This is a great primer for someone who’s looking to jump into Javascript with an OOP frame of mind - which just happens to be me.

    Great article.

  4. Piotr Usewicz

    WOW. Nice article. To be honest, it is the first time that I thought “Hey… Javascript is not that bad”. For years I wanted to stay away from Javascript as far as possible, because of the mentioned ugliness. But now, I think it is time to get my hands dirty with some JS code, mainly due to a fact that JSON is really cool, and what is more… it is clean! Thanks.

  5. Justin Perkins

    Whoa baby, you must’ve been working on that for a while ;)

    What’s the difference between what you’ve shown here (what I often call object literal notation) and the “other” JSON used for data exchange, commonly for AJAX responses?

    On the JSON Javascript page, it states “JSON is a subset of the object literal notation of JavaScript.”. What that says to me is JSON is a form of object literal notation, but object literal notation is *not* JSON.

    All that fuss aside, I find that debugging code written in object literal notation can be an absolute bear sometimes. A missing comma or a semicolon in the wrong place and you’ll be spending quite a while trying to locate the error. That’s mostly because Firefox quietly fails parsing the JavaScript.

  6. PJ Hyett

    Very nice article, thanks for writing it.

  7. Mike Papageorge

    Spell it with me: W-e-e-k-e-n-d.

    :-) (still reading - eyes sore)

  8. Jamie Fehr

    Interesting read. I have started writing javascript this way after reading the javascript behind moo.fx. Now I understand a whole lot better why this is good.

    Thank you very much.

  9. Dustin Diaz

    @Johan: I edited your post due to the code length and… formatting. Please do share your code with the world, I would just encourage that you post it on your own sandbox and link to it :) thanks

    @Jim: I’m glad I turned you onto this. But with or without me, you would have eventually discovered its usefulness. Don’t feel pressured to read the whole thing at once. Take a break, relax, come back later :)

    @PJ: Wow, I had no idea I was writing for action scripters. Very cool. I’m glad you found this useful!

    @Piotr: Yes, JavaScript can look nice! I feel your pain back from the days of not even wanting to write a single line of JavaScript due to its daunting syntax to begin with.

    @Justin: You bring a very valid and interesting point here that I didn’t bring up in the article. Although I have no clear answer, I would argue that JSON has been mistaken as being only a “data exchange format” when in fact, it is what it is: JavaScript Object Notation. It is indeed written in the literal notation, so… I don’t see a reason to differentiate the two. The link you provided to the JSON page, I too think what you have written (one is the other, but not the other way around). Either way, I’ve decided to not let it get me sidetracked. I’m sure we both know what this is about. And yea… I have been working on this for a while, lol.

    @PJ: Thanks man.

    @Mike: I was being nice. I figured there’s so much to read during the week, why not release this one on a Sunday ;) I hope your eyes get better soon. As I mentioned to Jim, take a break. Read the rest later.

    @Jamie: You’ll soon start to realize that Object Notation is what’s behind some of the most popular libraries out there.

  10. Justin Perkins

    Dustin, I just wanted to get your input on the matter, since there appears to be some different terminology being used. Like when I saw your article title, I thought it was going to be about the data exchange format ;)

    Great article.

  11. Dustin Diaz

    Well, consider it a myth debunker. Or, you could also ask Ryan for his thoughts on the matter. To me, object notation is object notation. Whether that’s “literal” or not. Meh. But still, hearing “Great Article” coming from you says something big. I definitely appreciate your feedback as always.

  12. Elliot Swan

    While I’m still sort of confused…It does sound useful.

    I haven’t gotten this far in DHTML Utopia yet, maybe I’ll have to skip ahead a little so I understand more of what you’re talking about…

  13. Michael Geary

    Your object literal examples are not JSON. JSON is a subset of the JavaScript object literal format. Specifically, it does not use unquoted names. JSON property names are always quoted. This eliminates all restrictions on property names: they can be any string value.

  14. Dustin Diaz

    Michael, I’m glad you’ve failed to see the point of the article and the discussion of the comments thus far. I am specifically talking about JavaScript’s Object Notation. Justin and I discussed some of the confussion behind JSON and literal notation… as some might have expected (like yourself) to hear about the data-exchange language, I did not want to focus on that part of it.

    I do believe that everything in the article does in fact still quality as writing JSON.

    Re: name/value pairs, you can indeed use unquoted names. Just try it. It works.

  15. Brad Neuberg

    Dustin, this is a high-quality, well written tutorial on JSON and proper OOP in JavaScript; good stuff, and thanks for writing it!

    Brad Neuberg

  16. Michael Geary

    Dustin, sarcasm doesn’t do any of us any good. How about leaving it out of the discussion?

    You seem to blame me for misunderstanding your article, but is it really fair to blame the reader for thinking you might be talking about JSON, when the article *says* it is about JSON, over and over again?

    Believing that your object literals are JSON doesn’t make it so. What is “Just try it. It works.” supposed to mean? That I can eval() one of those object literals and it will produce the correct result? Of course that will work, but eval() is *not* a JSON validator. eval() is a JavaScript parser, not a JSON parser.

    All valid JSON is also valid JavaScript, but not all valid JavaScript is valid JSON. A JSON parser that follows the JSON specification will not accept object literals with unquoted names.

    This doesn’t matter if you’re just using JavaScript to parse the object literals. But if you ever pass them to an actual JSON parser they will fail.

    At the risk of sounding like a nitpicker, here’s another little terminology error: “Functional programming” is not “programming with global functions instead of objects”. Functional programming is something else entirely:

    Functional Programming article on Wikipedia

    Your article has some fine information in it, and your enthusiasm for the subject comes across loud and clear. But there is also some misinformation, and it would serve your readers best to correct these errors.

    Keep in mind that we’re on the same team. I’m a major fan of JavaScript and JSON, and I appreciate articles like yours that help more people become familiar with these technologies.

  17. Chris Heilmann

    I agree that there is a lot of good information here, but I also agree that this post muddles up different concepts.

    JSON is primarily a data format for transfer. For web services and backend systems talking to another XML is wicked, but can be slow for AJAX applications as you need to parse the XML to become something useful for JS. JSON is a quicker way for other languages and JavaScript to talk to each other than XML is.

    The object literal is another thing, and I just published a quick introduction about it on my blog (and you link to it on the HP, thanks!)

    In the comments of my post and on AJAXian some people pointed out quite rightly that the object literal is a good thing, but restricts the OO abilitites of JavaScript a bit. I for myself am OK with sacrificing them for readability though.

    I guess the “wrong” term functional programming can be replaced by procedural programming.

  18. Michael Geary

    Having said all that, I want to apologize for something: My first comment pointed out an error in the article without acknowledging the value of the article–and there’s plenty of that to acknowledge.

    So let’s get our names straight, and then keep up the good work! :-)

  19. Michael Geary

    Oh, one more thing. :-) I don’t think I made this clear: property names in object literals can be any string, not just proper JavaScript names. For example, it is perfectly valid to have a function named “Mike & Dustin’s Cool Code”. All you have to do is quote the name:


    var obj = {
    "Mike & Dustin's Cool Code": function() {
    alert('Cool!');
    }
    }

    and call it like this:


    obj["Mike & Dustin's Cool Code"]();

    JSON requires the quoted names for all properties; JavaScript object literals do not require the quotes but allow them.

  20. randomcat.co.uk » Blog Archive » Javascript Object Notation

    […] Dustin Diaz - JSON For the Masses […]

  21. Joshua

    Can you add examples of functions which take paramaters? Thanks.

  22. PJ Hyett

    In Michael’s defense, the terminology is a bit confusing. When I saw the title, I thought you were going to talk about the data transfer format, but quickly understood you were referring to Javascript OOP instead.

  23. Justin Perkins

    PJ Hyett,
    Does this really classify as OO design? There are no classes and the code isn’t any less procedural than with out the object literal notation.

    This like a JavaScript best practices guide (at least part of a guide anyway).

  24. Michael Geary

    Well, the code does use objects and “this”. :-)

    Dustin, can you explain what this code (excerpted from one of the examples) does?


    var obj = {
    a : Object,
    b : Array
    };

    (Hint: It doesn’t do what you think.)

  25. Frank Manno

    Hey Dustin,

    Awesome article. It’s nice to see JSON getting the attention it deserves.

    I’m sure you know how much I love writing my JS in object notation… So on that note, preach on brother man!

    PS: Spacer GIF (aka Shim) is going to rock the alley! :)

  26. SIXFACE » Blog Archive » links for 2006-02-20

    […] » JSON for the masses (tags: javascript Programming) […]

  27. Dustin Diaz

    With all the confusion, I may just be tempted to change the name of the article to “Object Notation for the masses.”

  28. Christian Montoya

    Dustin, this is a great article, please give more examples or code snippets of this used properly.

  29. Frank Manno

    @Joshua,

    An example of a function that takes arguments would be something like:


    var myObj = {

    myMethod : function(strArgument){
    // Do with me what you will!
    }
    };

    HTH!

  30. Talking to myself… » Links: 2-20-2006

    […] » JSON for the masses (categories: javascript webdev ) […]

  31. Lap

    How can I create an object using JSON like the following?

    function person(height, weight) {
    this.height = height;
    this.weight = weight;
    }
    person.prototype.getHeight = function () {
    return this.height;
    }

  32. Bloggitation » links for 2006-02-21

    […] JSON for the masses (tags: programming) […]

  33. Frank Manno

    Lap,

    You could do so like this:

    var Person = {
    height : 0,
    weight: 0,

    getHeight : function(){
    return this.height;
    }
    }

    And you can call the function like:

    alert( Person.getHeight ); // Assuming you’ve set a height, otherwise returns 0

  34. Lap

    Thanks Frank,
    One other question is what can I pass the paramaters when I create the object?

    like I can do:

    var john = new Person(”5′10””, “150lb”);

    is it possible?

  35. Frank Manno

    Lap,

    I can see how people would confuse the constructor-style of Objects with JSON/Object notation.

    In that case what you would want to do is make use of an initialization function (I prefer to use “init”, as does Dustin):

    var Person = {

    weight: 0,
    height : 0,

    init : function(w, h){
    this.width = w;
    this.height = h;
    }

    getWidth : function(){
    return this.width;
    }
    };

  36. Frank Manno

    Lap,

    Sorry, I forgot to add the call to Person:

    var myPerson = Person.init(”5′10””, “150lb”);
    alert( myPerson.getWidth() );

    In this case, since you’re passing Strings, you may want to change the initial width : 0 and height : 0 to either width : null or width : “”.

    Hope that helps…

  37. Dustin Diaz

    Thanks Frank for clearing up some questions. I always enjoy it when the visitors have discussions among themselves. It takes a load off trying to have an answer for everything.

  38. Justin Perkins

    Frank,
    The only way that would work is if you explicitly pass back a reference to the object (return this).

    You don’t instantiate object literals because there is nothing to instantiate, they are not classes. They are a scope-safe means of wrapping your code so that it plays well with others.

    For example, this doesn’t work:
    var firstPerson = Person.init(”5′10′”, “150lb”);
    var secondPerson = Person.init(”4′10′”, “120lb”);

    There is no instantiation, only a static object.

    Object literals does not equal OO.

    Nevermind that fact that a person’s width is *not* their weight ;)

  39. Justin Perkins

    Here’s a pretty helpful intro to OO Javascript, btw:
    http://www.javascriptkit.com/javatutors/oopjs.shtml

  40. Gilles Dubois Bookmarks » links for 2006-02-21

    […] JSON for the masses (tags: javascript json)   […]

  41. Dustin Diaz

    Yes, if you wanted true OO, you would create an actual generic object that can be instantiated many times.

    However I’ve been able to do anything i want to using Object Literals. If you were to ask Stuart Langridge as well, he would feel the same.

    Besides, using the literal is generally faster anyway, so all the better :D

  42. Justin Perkins

    No, I absolutely agree with you there Dustin. It’s just that I’m seeing some terms thrown around here and it seems to be confusing people.

    Questions like those posed by Lap and the code samples by Frank only further confuse things for newbies. You don’t instantiate an object literal. That’s all I meant to say.

  43. Lap

    It means that we cannot use JSON to instantiate object? is it correct? So, we cannot use JSON to write a class in javascript?

  44. Frank Manno

    Justin,

    You’re totally right. After reading my code again, I’m not sure why I had:

    var myPerson = Person.init(…);

    That’s totally incorrect. I guess after re-writing a few Java classes today, my mind was in another state. Thanks for clearing that up. My apologies for the confusion I may have caused.

  45. Frank Manno

    Here is some corrected code that I’ve tested:

    var Person = {

    weight: “”,
    height : “”,

    init : function(h, w){
    this.height = h;
    this.weight = w;
    return this;
    },

    getWidth : function(){
    return this.weight;
    }
    };

    var myPerson = new Person.init(”5′10””, “150lb”);
    var myPerson2 = new Person.init(”6′11””, “160lb”);

    alert(myPerson.height);
    alert(myPerson2.height);
    alert(myPerson.height);
    alert(myPerson2.height);

    The reason for the 4 alerts is to make sure that the 2nd object doesn’t overwrite the first (which was happening when not using the new keyword — obviously).

    Justin… Thanks for catching the width/weight issue. ;)

  46. Frank Manno

    Okay,

    This is what I get for posting this early in the morning… Dustin, please delete my last post. It’s incorrect. I realized I wasn’t accessing the weight using the “getWeight()” method. Doing so results in an error (getWeight is not a function).

    Again… My apologies for the confusion. I shouldn’t be posting until both my eyes have opened up. :D

  47. JavaScript Round-up » Web 2.0 Blog

    […] First up Dustin Diaz has two great posts, the first about JSON for the Masses, does an excellent job of introducing JSON and how great it is (I’m already a believer!). Your co-workers will love you for writing in JSON because it will most likely not conflict with their scripts that are being called within the same web documents. […]

  48. Justin Perkins

    Frank,
    Regardless of *how* you access the object’s properties (accessors or direct property access), the bigger issue is you are trying to instantiate an object literal.

    You do not instantiate object literals. Simply putting the “new” keyword before the function call does not make it so. What you’re doing there is forcing JavaScript to interpret the “init” function as if it is a class.

    That’s why using the keyword “this” is very misleading (and why I don’t use it with object literals). ‘this’ implies that an instance of an object has been created, yet it is impossible to do so with object literals.

    With languages with proper OO syntax, it is impossible to use “this” in a static context. It makes no sense and by allowing it’s use in object literal’s it only confuses people.

  49. Frank Manno

    Justin,

    You’re completely right. The “incorrectness” of my post wasn’t that I wasn’t using an accessor to retrieve the value; what was incorrect was my attempting to instantiate the object literal.

    In this case, the “prototype” is simply the best (only?) way of truly creating re-usable objects. By the way, the article you linked to will be really helpful for people to truly understand OO in JS.

  50. jagthedrummer

    This is a great article and I completely agree that this is a great way to keep functional blocks of code sepearted from each other. It seems there’s a bit of confusion about the diffences between this technique and a real OO data obejct. I just posted an article that details how to make reusable ‘data object’ thingys (yeah, that the technical term).


    http://test.rhythmandcode.com/pages/home_page/code/javascript_objects/web_page.xml

    You can read the long version there, or the sort version is basically this.

    SimplePerson = function(name){
    this.name = name;

    this.getName = function(){
    return this.name;
    };

    this.setName = function(name){
    this.name = name;
    };
    }

    Then use it:

    var p1 = new SimplePerson(”Mr. Foo”);
    var p2 = new SimplePerson(”Mr. Bar”);

    alert(p1.getName()); //”Mr. Foo”
    alert(p2.getName()); //”Mr. Bar”

    p1.setName(”Mr. Smooth”);
    alert(p1.getName()); //”Mr. Smooth”
    alert(p2.getName()); //”Mr. Bar”

  51. Justin Perkins

    Normal functions can be objects too..

    function Person(name){
    this.name = name;
    }

    var firstPerson = new Person(”John”);
    var secondPerson = new Person(”Dustin”);

  52. Sensient»Blog Archive » JSON and AJAX

    […] The Particletree weblog has a great tutorial on Preloading Data with Ajax and JSON. This is a neat technique to help speed up the responsiveness of web applications. More JSON for the masses is here. • • •   […]

  53. Episode 04: Paul Boag Interview

    […] The last news bit can be found on this very website where I covered the fundamentals of writing JavaScript using the Object literal. No more than a few hours later Ryan from ParticleTree later gives more love to JSON however a day before my entry was posted to this site, Chris Heilmann writes some practical advice on even more love on the object literal. […]

  54. phpied.com » Blog Archive » Bitwise operations in JavaScript

    […] Don’t you just love discovering new treasures?! Today I stumbled upon a Google/ex-Urchin javascript - urchin.js. Scrolling down the file with no apparent purpose in mind, I though I saw some >> and <<s. A second look? Yep, these do look like bitwise operators. In JavaScript? In the poor old insulted, sweared-upon, ignored, dumped to the juniors, forbidden, forgotten, no-good cheap status-bar-changing-only, blinking and blinding and obtrusive, cursor-following JavaScript. In the “abused, misunderstood, and kicked around like the poor step-child as known in fairytales” JavaScript (Dustin Diaz). […]

  55. Nate Cavanaugh

    First of all, let me say thank you!

    Sitepoint has a very thorough article from 01 or 02 that goes into this, but he didnt get anywhere close to the amazing simplicity and clarity that you’ve provided.

    I have to use this method from now on :D

    Lastly, I do have a question, in situations like above, where you’re calling a member method in an addEvent (the this caveat mentioned above), how do you call member properties if you cant use this?

    Do you have to refer to the object directly? And will that scale if you create multiple objects from this?

    Hopefully my question wasnt too obfuscated, but Im just trying to get around the “Careful how you use this” example.

    Thanks Dustin!

  56. Max Erickson

    Regarding the war of the words:

    http://www.json.org/

    The term ‘json’ was coined by Crockford. JSON happens to match up very well with the syntax for javascript object literals, but it isn’t the same thing. People are confused because your usage is different than json.org and yahoo:

    http://developer.yahoo.net/common/json.html

    I’m all for words being defined by thier popular usage, but calling object literals json is creating the confusion here.

  57. Jordy

    what about constructors, prototype and nested objects

  58. Joel Hughes

    Hi,
    thanks for a great article, food for thought indeed.

    One issue I’d like to discuss is how functions triggered via events can access object properties.

    e.g.
    in your example:
    var jack = {
    a : Object,
    init : function() {
    this.a = document.getElementById(’jane’);
    this.a.addEventListener(’click’,this.alerter,false);
    this.run();
    },
    run : function() {
    this.alerter();
    },
    alerter : function() {
    alert(this.id);
    }
    }
    function pageLoader() {
    jack.init();
    }
    window.addEventListener(’load’,pageLoader,false);

    Lets pretend that you have set up some other properties in jack, e.g. name:”jack”.

    Now, within the alerter function, is the only way to access the name property as “jack.name”? (rather than “this.name” as would seem correct) - if that is the case then I suppose that ‘alerter’ is almost a static/class method (maybe there could be a naming convention to indicate as such).

    Also, is there no way around having to have the “pageLoader” method?

    Finally, if we were writing lots of these type of scripts I take it that we should try to come up with a unique name for the object/pageloader to stop clobbering other scripts which might be included in the same document.

    interesting stuff!

    regards

    Joel Hughes

    p.s. would be v cool to have a command line CPAN/PEAR like repository tool for javascript libraries.

  59. Joel Hughes

    hmm..almost answering my own questions here but just to post for completeness sake…

    The Yahoo Event library mentioned elsewhere on your blog (http://developer.yahoo.net/yui/event/) solves the problem of passing the object back to the event handler.

    Also, to get rid of ‘pageLoader’ ,
    window.addEventListener(’load’,pageLoader,false);
    becomes
    window.addEventListener(’load’,function(){jack.init();},false);

    regards

    Joel

  60. Raj

    Good work Dustin, alot of useful information.

    Thanks,
    Raj

  61. Shekhu

    Using new method to instantiate is worthless. This method doesn’t support functions, objects. It throws error
    Given Given Below:
    var ElemBehaviour = {
    elem : “”,
    init : function(x)
    {
    this.elem=window.document.getElementById(x); },
    getTitle :function(){alert(123);}
    }
    };

    Then instantiating the Element
    var elemBehaviour1 = new ElemBehaviour.init(this.id); elemBehaviour1.getTitle();

    Throws error

    Any suggestions..

  62. Topper

    function Person(height, weight) {
    this.height = height;
    this.weight = weight;
    }
    Person.prototype = {
    getHeight: function () {
    return this.height;
    },
    getWeight: function () {
    return this.weight;
    }
    }

  63. Stephen Clay

    Like some of the commenters, you should include the semicolon after each assignment statement.
    var obj = {
    /* properties:values */
    };
    var obj2 = {
    /* properties:values */
    };
    I’ve run into Javascript errors in Opera with adjacent statments like this without the semicolons. Another reason why automatic semicolon insertion was a sucky idea.

  64. Mindsack » Blog Archive » SpiffY!Search Update

    […] Thanks in (very large) part to Dustin Diaz JSON for the Masses, I’ve been able to wrestle SpiffY!Search into a form I like quite a bit better than before. It’s smaller, lighter, faster, more flexible in narrow columns, and has a no-script fallback. The Wordpress plugin should come up and run inside the default template with no modifications; I’m also working on Movable Type and Serendipity versions. […]

  65. Anh

    what is the disadvantage of following notation?

    function Class1() {
    var prop1 = 1;

    this.method1 = function() {
    return 1 + prop1;
    }
    }

  66. Chu Yeow

    Sorry for adding noise to the comments, but I really just had to say that I only recently discovered your blog (just as I have only recently discovered that JavaScript doesn’t suck - yes, I was one of those people who spoke bad about JavaScript mindlessly), and I like it! I’m getting your podcast right now as we speak ;)

    And I notice you have lots of SitePoint books in your library (mine’s in there, woohoo!)… Would you happen to be a SitePoint “personality” (i.e. forum staff or a big members)?

    More on-topic, yes I can fully appreciate how JSON would totally help with what I have been working with right now… Our scripts are quite a mess and the global namespace is polluted (to say the least), and I almost puked blood when I realized that 1) there was an onload handler attached to the <body> tag that overwrote my “safe” addLoadEvent() call, 2) the Firefox JavaScript console wasn’t saying anything when I had syntax errors in my JavaScript. I really wanna rip out everything and re-organize it so I don’t spend an entire day doing stuff that would normally take an hour.

    Oh well, I am learning and finding it a blast, and articles like yours help. Keep it up!

  67. DD

    I’m not convinced this is a style that can be used for large JS Object Oriented designs. Take this (small) example:

    I want an object that can hold the width and height of some land and offer a function to return the area (width * height) of it. Using regular OOJS it would look like this:

    function SomeLand(n,w,h,u){
    this.name=n;
    this.width=w;
    this.height=h;
    this.units=u;
    this.area=function(){return this.width*this.height;}
    };
    var obj=new SomeLand(’garden’,50,60,’metres’);
    alert(obj.name +”=”+ obj.area() +” sq.”+ obj.units);

    Compact and efficient. Using the JSON style has two problems for me. (a) it’s not as compact, (2) it doesn’t work for additional methods to the init function. Here’s an example I played around with. The lines commented with //# are the ones that didn’t work:

    var SomeLand2={
    name:”",
    width:0,
    height:0,
    units:”",
    init:function(n,w,h,u)
    {
    this.name=n;
    this.width=w;
    this.height=h;
    this.units=u;
    return this;
    }
    //# ,area:function(){return this.width*this.height;}
    };

    //# SomeLand2.prototype.area=function(){return this.width*this.height;};

    //# SomeLand2.prototype={area:function(){return this.width*this.height;}};

    var obj2=new SomeLand2.init(’garage’,3,6,’metres’);

    //# alert(obj2.name +”=”+ obj2.area() +” sq.”+ obj2.units);

    //OK, I’ll calculate it myself then
    alert(obj2.name +”=”+ (obj2.width*obj2.height) +” sq.”+ obj2.units);

    I think JSON style notation is useful for exchange objects but isn’t advantageous over regular OOJS for defining objects with properties and methods. Even if there is a correct syntax for creating the area function I wanted in this example, it’s still less compact and clear than the traditional example.

    ~dd

  68. Arjen

    Hi,

    I’ve been programming OO javascript for several years now and I love it. For my notation I use the good ol MyObject.prototype.aMethod = function (…) {…}

    I am tempted to look in the Object Literal way of doing things, but not being able to work with concepts like Classes and Instances puts me off.

    Who can explain to my how OL solves this issue?

    Thanks,

    Arjen

  69. Ajax Language Switcher for Basic Bilingual at freshlabs journal

    […] Der JavaScript-Teil des Plugins ist nun als Object Notation notiert. Developer’s Edition: Dieses Plugin ist noch in der Beta-Phase und vorerst nur fortgeschrittenen Benutzern empfohlen. Einige Variablen müssen für die individuelle Einrichtung geändert werden. Ein wenig Erfahrung mit JavaScript and PHP ist bei der Einrichtung von Vorteil. […]

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

    […] For 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.” […]

  71. Yea um, so… I added sound to YUI Tetris

    […] Thanks to Scott Schiller and his dandy Sound Manager (from ages ago) which allows you to embed audio into your webpage and fire them at will with JavaScript. Sounded simple enough so I dropped in the soundmanager.js file, a .swf, and then an xml file to define my sounds… then Voila! it was a piece of cake. It was as easy as dropping in the appropriate triggers in particular points of my tetris script such as moveLeft, moveRight, drop, nukeLines or rotate. I experienced first hand the benefits of writing in Object Notation when I had to go back and do some editing… […]

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

    […] La seconda sintassi, presente anche in altri linguaggi, è detta “Object Literal” e risulta molto utile per ordinare in gruppi indipendenti alcune variabili e funzioni che lavorano in cooperazione. (Esempi a proposito sono segnalati nei post di Dustin Diaz e Chris Heilmann sull’argomento). Nel 2002 il developer Douglas Crockford ha pensato di utilizzare la notazione letterale come un formato per lo scambio di dati definendo una particolare sintassi in questa pagina introduttiva (qui la traduzione in italiano). Come potete osservare nei vari schemi, gli elementi principali della sintassi JSON sono: […]

  73. Gen-X-Design | Ian Selby » JSON = More Gooder JavaScript

    […] If you don’t know what JSON is, you need to stop reading this article and head over to Dustin Diaz’s site right away and read his article, JSON for the Masses. Then you need to try it for yourself. It’s that cool. Here are some reasons to use JSON (according to Dustin): […]

  74. The X from JSON | Central Scrutinizer (en. vers.)

    […] The second syntax, that you can find in other languages too, is called “Object Literal” and is useful to arrange in groups some variables and functions that work together. (An example of this is done by general function like init, as suggested in Dustin Diaz and Chris Heilmann’s posts on the topic). In 2002 Douglas Crockford thinked to use the object literal to create a format for the data-interchange defined in this introduction page. As you can seen in various schemas, the principal elements of the JSON syntax are: […]

  75. Yamin

    I’m new to JSON concept, can anyone help me out how JSON work & how to install it!

  76. sAm

    Easy examples and necessary files are needed to explore JSON clearly

    if anyone want to help me please send necessary documents to my email or give me any URL as early as possible

  77. Gen X Design | Ian Selby » JSON = More Gooder JavaScript

    […] If you don’t know what JSON is, you need to stop reading this article and head over to Dustin Diaz’s site right away and read his article, JSON for the Masses. Then you need to try it for yourself. It’s that cool. Here are some reasons to use JSON (according to Dustin): […]

  78. Thomas Frank

    Excellent article!

    As I scan through the comments I see quite a few complaining that JSON does not support classes.

    I written a small script for this called ClassyJSON - and an article about it:

    http://www.thomasfrank.se/classy_json.html

  79. Russ

    I have been using JSON for a while but have always had to reference the object rather than “this”. In the example below (adapted from your great article above), this.sample is undefined until set in the test() function.

    I have therefore been using alert(json.sample) instead of alert(this.sample) to get this to work.

    Am I missing something fundamental here? :-(

    var json = {
    			// test string property
    			sample : "sampleValue",
    			// test function
    			test : function() {
    				alert (this.sample);
    				this.sample = "editedSampleValue";
    				alert (this.sample);
    				},
    			// addEvent function from http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html
    			addEvent : function (obj, type, fn) {
    				if (obj.addEventListener) obj.addEventListener(type, fn, false);
    				else if (obj.attachEvent)	{
    					obj[”e”+type+fn] = fn;
    					obj[type+fn] = function() { obj[”e”+type+fn]( window.event ); }
    					obj.attachEvent(”on”+type, obj[type+fn]);
    					}
    				}
    			}
    
    		//	obj.test();
    	 json.addEvent(window, “load”, json.test);
  80. Dustin Diaz

    Hi Russ, I cleaned up your example so it was easier to read. Next time just use <pre><code> when inserting code (Iknow, I should note that when commenting).

    Anyway, I don’t see where ‘obj’ is getting defined, but naturally, ‘this’ when called from ‘obj.test()’ is the obj, and not ‘json’. However if you called ‘json.test()’ then the scope for ‘this’ would be as you expected.

  81. Russ

    Thanks, Justin. The obj.test() is an old commented line. Correct script attached below.

    I am calling json.test() but my issue is that the test() function does not recognise the value of this.sample (I get an alert of “undefined” when running the script below). I was under the impression that this the value of the sample variable would be available to all member functions of the json class by referencing with this.sample? Hope that makes sense.

    
    var json = {
    			// test string property
    			sample : "sampleValue",
    			// test function
    			test : function() {
    				alert (this.sample);
    				},
    			// addEvent function from http://www.quirksmode.org/blog/archives/2005/10/_and_the_winner_1.html
    			addEvent : function (obj, type, fn) {
    				if (obj.addEventListener) obj.addEventListener(type, fn, false);
    				else if (obj.attachEvent)	{
    					obj[”e”+type+fn] = fn;
    					obj[type+fn] = function() { obj[”e”+type+fn]( window.event ); }
    					obj.attachEvent(”on”+type, obj[type+fn]);
    					}
    				}
    			}
    
    	 json.addEvent(window, “load”, json.test);
    
    
  82. Dustin Diaz

    Hi Russ, re-read the section where I talked about the “this” keyword in the article.

  83. dai

    I think you’ve got some voodoo going on with your initializer and inializer in your last block of code ;)

  84. Ashish

    I am kind of new to JSON. One question I have is about the right place to call the init() function.

    In traditional way , I used to make the init() function private , and then call it inside the class declaration , something like

    MYClass = function()
    { function init() { //..}
    init()
    }

    This free the user from remembering to call init() everytime. What do you think of this approach ? Can it be done using JSON.

  85. dd

    Hey Russ, this examples works just fine for me. It alerts “sampleValue” and then “editedSampleValue” as you’d expect. I took out the addEvent because it’s unnecessary and just makes the example bigger for no good reason.

    
    var json = {
    	sample : "sampleValue",
    	test : function() {
    		alert (this.sample);
    		this.sample = "editedSampleValue";
    		alert (this.sample);
    	}
    }
    
    json.test();
    
    
  86. Mindsack » Blog Archive » Hacking Scope in Javascript

    […] I’ve either fixed something or made it worse; given my limited knowledge of object-oriented Javascript, it could go either way. Here’s the problem: I’ve been mucking about with Dustin Diaz’s advice on structuring one’s Javascript inside objects, as documented in JSON for the Masses. Simple example: […]

  87. Johan Sundström

    I also encourage changing the title of the article to “object notation for the masses”, and (ideally) remove the confusing JSON references, or note that you use the name tag very liberally for what the words mean, not what the standard that also picked up those words for a name means.

    So while you promote a very good coding practice, you also water out the name of a standard, adding up to naming confusions, which is unfortunately already one of the larger javascript plagues (starting at the very name of the language, which improperly hints of a close relation to java).

    That Douglas Crockford didn’t pick a name that can not be interpreted as meaning something broader than what his standard then encompasses, is of course not your fault, but it would be nice of you not to water it out anyway, for the good of the javascript community as a whole. People tend to assume that people insightful in one spot are also authoritative in related fields, so your words do carry some weight here, whether correct or not. :]

  88. Shawn

    After reading your tutorial I decided to do a JSON tutorial mashup. At least the output…

    I used http://www.econym.demon.co.uk/googlemaps/basic12.htm tutorial which shows how to read JSON output to plot coordinates etc. and this page to figure out the rest. I also used your rock solid addEvent function to start the show. Oh, and a dash of Prototype.js in there too.

    The map example is at:
    http://www.shawngo.com/google-maps-tutorial-mashup-example2.php

    The only problem I ran into was when I tried to call a function from a GMarker when pulling it out of an array. It tries to call the function on a String and not the Gmarker object.

    Great JSON article btw :)

    Shawn

  89. Rob

    Totally off topic but why is it so easy to miss out the ‘t’ in iniialiser? I swear my keyboard has that rare bone disease that means you can’t get the t in plane-arium… or ini-ialiser. That’s assuming keyboards have bones. And diseases.

  90. J-Lo's Butt

    What’s the correct pronunciation for JSON? Is it exactly the same as the name Jason? Or is the J pronounced as in Jay, and the SON as in SONNET ? J-SON ?

  91. epiphantastic » Blog Archive » Accessible Ajax Forms

    […] I love JSON. It’s just so simple and intuitive. I can write it quicker than XML and it’s easier to process. So it was my obvious choice to define my validation rules. Here’s the code used in my example: […]

  92. Gaurav

    Hi Dustin

    Very useful information, it appears it will be quite useful for me. I’ll try to find more about it.

  93. Peter Foti

    Interesting read.

    But I think I’m on the same sticking point as several others. I’m already using OOD methodologies via the prototype, so the method described in this article seem like a step backwards. For example, here’s how I might create a Person “class” and how I’d create multiple “instances” of the Person class:

    
    function Person(name, height)
    {
        this.name = name;
        this.height = height;
    }
    Person.prototype.getName = function()
    {
        return this.name;
    };
    Person.prototype.getHeight = function()
    {
        return this.height;
    };
    
    var Peter = new Person( "Peter","5ft 11in");
    var Bob = new Person( "Bob", "6ft");
    

    With Object Literal Notation, it seems to me as though you can only work with one “instance” object at a time.

    Perhaps there is some fundamental concept that I’ve missed, or perhaps not. It’s quite possible that this is only meant for cases where you’d work with a single instance of an object. I’d love to hear someone address this.

    Thanks.

  94. J-Lo's Butt

    I agree Peter, that seems to be the case. JSON = “OBJECT” notation, allowing you to create an object, to which you can add prototypes, but it’s only one object.

    The example you made above is more of a class notation. I’m also sticking with this class notation for now.

    Still nobody wants to tackle the JSON pronunciation ?

  95. Thomas Frank

    @Peter:
    This would do the same thing as your example in a JSON-esque style:

    function Person(name,height){
    	return {
    		name:name,
    		height:height,
    		getName:function(){
    			return this.name
    		},
    		getHeight:function(){
    			return this.height
    		}
    	}
    }
    
  96. Thomas Frank

    @Peter:
    Forgot to say

    // this would still work of course:
    var Peter = new Person( "Peter","5ft 11in");
    var Bob = new Person( "Bob", "6ft");
    
    // but so would this (omitting the "new" keyword):
    var Peter = Person( "Peter","5ft 11in");
    var Bob = Person( "Bob", "6ft");
    
  97. Peter Foti

    Thanks for that example.

    My other question, though, is what sort of efficiency difference is there between the object literal format and a prototype based format? With the object literal format, doesn’t each and every object created with this method have a copy of the same methods? With the prototype method, there’s only one copy of the prototype methods, making the prototype object an ideal place for class methods. Thus, via inheritance of the prototype, the amount of memory required for each object decreases.

    Thanks.

  98. Thomas Frank

    @Peter:
    However, if you want to be able to add members to the class through prototype you would have to keep your “new” and do it slightly differently:

    function Person(name,height){
    	var obj={
    		name:name,
    		height:height,
    		getName:function(){return this.name}
    	}
    	for(var i in obj){this[i]=obj[i]};
    }
    
    var Peter = new Person( "Peter","5ft 11in");
    var Bob = new Person( "Bob", "6ft");
    
    Person.prototype.getHeight=function(){return this.height}
    
  99. Thomas Frank

    @Peter:
    Didn’t see your last post before my last one. Sorry!

    Efficiency: You are probably right - let me think about that one a bit… Thanks!

  100. Peter Foti

    Looks like we both posted at the same time. :)

    Note, this still looks to be quite inefficient to me, as it doubles the memory requirements by copying obj properties to Person properties.

  101. Peter Foti

    Hehehe… did it again. :)

  102. Thomas Frank

    @Peter:
    So I did boot up the old brain (takes forever nowadays - must reformat) and gave effiency som thought.

    Heres what I came up with:

    // The function jsonClass is a constructor of constructors
    // that we can reuse for different object classes
    
    jsonClass=function(argNames){
    	var F=function(){
    		var m=argNames;	var a=arguments; var u;
    		for(var i=0;i
  103. Thomas Frank

    @Peter
    Ups no > allowed let’s try again:

    // The function jsonClass is a constructor of constructors
    // that we can reuse for different object classes
    
    jsonClass=function(argNames){
    	var F=function(){
    		var m=argNames;	var a=arguments; var u;
    		for(var i=0;i>m.length;i++){
    			if(a[i]===u){continue};
    			this[m[i]]=a[i];
    		}
    	};
    	return F;
    };
    
    // So now we can start defining our classes
    // in a way that is efficient and json-esque
    
    Person=jsonClass(["name","height"]);
    Person.prototype={
    	name:'default value',
    	height:'default value',
    	getName:function(){return this.name},
    	getHeight:function(){return this.height}
    };
    
    var Peter = new Person( "Peter","5ft 11in");
    var Bob = new Person( "Bob","6ft");
    
  104. Thomas Frank

    Hm, that went a bit wrong too. Last try (please get a preview mode Dustin?) and now it should be the right code:

    // The function jsonClass is a constructor of constructors
    // that we can reuse for different object classes
    
    jsonClass=function(argNames){
    	var F=function(){
    		var m=argNames;	var a=arguments; var u;
    		for(var i=0;i<m.length;i++){
    			if(a[i]===u){continue};
    			this[m[i]]=a[i];
    		}
    	};
    	return F;
    };
    
    // So now we can start defining our classes
    // in a way that is efficient and json-esque
    
    Person=jsonClass(["name","height"]);
    Person.prototype={
    	name:'default value',
    	height:'default value',
    	getName:function(){return this.name},
    	getHeight:function(){return this.height}
    };
    
    var Peter = new Person( "Peter","5ft 11in");
    var Bob = new Person( "Bob","6ft");
    
  105. Thomas Frank

    @Peter:
    Of course I couldn’t help expanding that a little bit. Let me know what you think:

    // A constructor of constructors...
    Array.prototype.jsonClass=function(){
    
    	// Remember the array as x in closures/inner functions
    	var x=this;
    
    	// Create our object constructor
    	var constr=function(){
    		var a=arguments; var u;
    		for(var i=0;i<x.length;i++){
    			if(typeof x[i]=="object"){
    				for(var j in x[i]){this[j]=x[i][j]}
    			};
    			if(typeof x[i]!="string" || a[i]===u){continue};
    			this[x[i]]=a[i];
    		}
    	};
    
    	// Prototype based inheritance of all superclasses
    	var nextProto=new function(){}();
    	for(var i=0;i<=x.length;i++){
    		var a=x[i]||constr;
    		if(typeof a=="function"){
    			a.prototype=nextProto;
    			nextProto=new a();
    		}
    	};
    
    	// Add a method to the constructor that lets us add
    	// members to a class (and subclasses) after it has
    	// been created
    	constr.addMembers=function(obj){
    		for(var i in obj){constr.prototype[i]=obj[i]}
    	};
    
    	// Return a our object constructor
    	return constr
    };
    
    // So now we can start defining our classes
    // in a way that is efficient and json-esque
    
    Person=[
    	"name","height",
    	{
    		name:'default value',
    		height:'default value',
    		getName:function(){return this.name},
    		getHeight:function(){return this.height}
    	}
    ].jsonClass();
    
    Student=[
    	"name","height","grade",
    	Person,
    	{
    		grade:"C",
    		getGrade:function(){return this.grade}
    	}
    ].jsonClass()
    
    // Some tests
    
    var Bob=new Student("Bob","6 ft","A");
    alert(Bob.getName()+"\n"+Bob.getHeight()+"\n"+Bob.getGrade())
    
    alert(Bob.cool)
    Person.addMembers({cool:1})
    alert(Bob.cool)
    
  106. Thomas Frank

    Published an article about it:
    http://www.thomasfrank.se/classier_json.html

  107. Peter Foti

    @Thomas
    Wow. :-)

    My initial reaction was “Ugh!” It looked like jumping through a lot of hoops just to duplicate the existing prototype functionality. Upon further inspection, I have to say this is quite clever, and interesting to say the least.

    I will admit, though, that it’s hard to tell exactly when and where the memory is being used. Also, I would expect that I could do this:

    var Jim=new Person(”Jim”,”5 ft”);
    alert(Jim.getName() + ” - ” + Jim.getHeight());

    But it returns ‘default value’ for both of those.

    All in all, this still “looks” convoluded to me. Without better understanding of what it’s doing I can’t condem it, but I also can’t endorse it. :-)

    Also, the YUI already provides a way to “extend” a class. Just an FYI.

    I will admit you put a lot of thought into that example, but I’m still not sold.

  108. Peter Foti

    Oh, I see you posted again… I’ll go read your article now.

  109. Thomas Frank

    @Peter:
    Thanks for your comments! Much appreciated!

    You found a bug too I can see. Of course you should be able to set object values when you make a new object instance. This line in the code above is the culprit:

    for(var j in x[i]){this[j]=x[i][j]}
    

    Change it to

    for(var j in x[i]){this[j]=this[j]!=u?this[j]:x[i][j]}
    

    and we should be home safe. (Just did on my own site).

    So thanks for finding the bug and for your comments. Whether to prefer this one to your more traditional approach is partly a matter of syntax taste I think.

    Thanks for the info about YUI. I promise I will have a look at YUI and the other monster libraries some rainy day ;-).

  110. Peter Foti

    @Thomas
    Impressive. You could probably call this a framework. Again, I still don’t fully understand the memory implications with your example, but even so, I find your example very interesting.

  111. Thomas Frank

    @Peter:
    Memory implications:

    Did some tests in Firefox 1.5.06 Windows:
    I created 10000 Students (a subclass to Person as in the example above) using my new way and your traditional way:

    My way:
    1668 kB
    171 bytes / object
    750 ms - time taken

    Trad way:
    1474 kB
    151 bytes / object
    300 ms - time taken

    So the memory usage seems neigh on identical.
    But it is around 100% slower. In my work I wouldn’t worry about the speed difference - but that all depends on the size of your app/data I suppose.

  112. Thomas Frank

    I apologize for sloppy testing - but I found another bug, that broke inheritance after one generation… Fixed it. Hopefully no more quirks now.

    Here’s the new code:

    Array.prototype.jsonClass=function(){
    	var x=this;
    	var constr=function(){
    		var a=arguments; var u;
    		for(var i=0;i<x.length;i++){
    			if(typeof x[i]=="object"){
    				for(var j in x[i]){this[j]=this[j]!=u?this[j]:x[i][j]}
    			};
    			if(typeof x[i]!="string" || a[i]===u){continue};
    			this[x[i]]=a[i];
    		}
    	};
    	var nextProto=false;
    	for(var i=0;i<=x.length;i++){
    		var a=x[i]||constr;
    		if(typeof a=="function"){
    			a.prototype=nextProto||a.prototype;
    			nextProto=new a();
    		}
    	};
    	constr.addMembers=function(obj){
    		for(var i in obj){constr.prototype[i]=obj[i]}
    	};
    	return constr
    };
    
  113. Peter Foti

    @Thomas
    Mind if I ask what tool you’re using for speed tests and memory usage?

  114. Thomas Frank

    @Peter:
    I’m a simple man. ;)

    For speed tests I do

    startTime=new Date().getTime();
    // some loop iterated a lot of times to
    // reduce error margin
    endTime=new Date().getTime();
    alert("That took "+(endTime-startTime)+" ms");
    

    For memory test I fire up Windows Task Manager, put an alert in my js code before the place I want to measure from and right after it.
    1) Write down memory usage of the browser.
    2) Press ‘Ok’ for the first alert.
    3) Write down memory usage again.
    4) Press ‘Ok’ for the second alert.
    5) Do the maths.

  115. Peter Foti

    @Thomas
    Simple is good. :-)

  116. gert cuykens

    function Person(name,height){
    return {
    name:name,
    height:height,
    getName:function(){
    return this.name
    },
    getHeight:function(){
    return this.height
    }
    }
    }

    how do you make name:name, private the json way ?

  117. gert cuykens

    Would this work too ?

    function Person(name,height){
     private=
     {
      private_name:name,
      private_getName:function(){return this.name},
     }
      public=
     {
       height:height,
       getHeight:function(){return this.height}
      }
     return public
    }
    
  118. gert cuykens

    function Person(name,height){
     var privateClass=
     {
      private_name:name,
      private_getName:function(){return this.name},
     }
      publicClass=
     {
       height:height,
       getHeight:function(){return this.height}
      }
     return publicClass
    }
  119. gert cuykens

    function person(name,height)
    {
     var privateClass=
     {
      private_name:name,
      private_getName:function(){return this.name}
     }
     var publicClass=
     {
      height:height,
      getHeight:function(){return this.height},
      getPrivateClass:function(){return privateClass}
     }
     return publicClass
    }
    me=person("John","6\"4")
    alert(me.getPrivateClass().private_name)
    alert(me.height)
    

    http://www.webdeveloper.com/forum/showthread.php?p=632360#post632360

  120. gert cuykens

    function Person(name,height)
    {
      var privateClass=
      {
        private_name:name,
        private_getName:(function(){return this.name})
      }
      this.height=height;
      this.getHeight=function(){return this.height};
      this.getPrivateClass=function(){return privateClass};
    }
    
    me=new Person("John","6\"4")
    me.prototype.age='25'
    alert(me.getPrivateClass().private_name)
    alert(me.height)
    alert(me.age)
    

    http://www.webdeveloper.com/forum/showthread.php?p=632371#post632371

  121. gert cuykens

    function Person(name,height)
    {
      var privateClass=
      {
        private_name:name,
        private_getName:(function(){return this.name})
      }
      this.height=height;
      this.getHeight=function(){return this.height};
      this.getPrivateClass=function(){return privateClass};
    }
    
    Person.prototype.grow=function(){this.height++;}
    
    me=new Person("John",7)
    me.grow()
    me.age='25'
    alert(me.getPrivateClass().private_name)
    alert(me.height)
    alert(me.age)
    

    http://www.webdeveloper.com/forum/showthread.php?p=632382#post632382

  122. gert cuykens

    
    Person=function(name,height)
    {
      var private=
      {
       name:name,
       b:(function(){alert(name+' born')}),
       age:1,
       height:height
      }
      this.public=
      {
       name:(function(){alert(private.name)}),
       age:(function(){alert(private.age)}),
       height:(function(){alert(private.height)})
      }
      private.b()
      this.public.age()
    }
    
    Person.prototype.height=function(){this.public.height()}
    
    me=new Person("John",7)
    me.height()
    me.public.height()
    
  123. Saiaman

    Does anybody got some String or DocXML prototype in order to transcript XML nodes or documents into JSon objets.

    The main aim is to use XML for describing objects ( remote objects ).

    thx

  124. Tanny O'Haley

    @Nate and @Russ,

    To pass parameters with addEvent() use an anonymous function. From your anonymous function pass the parameters. That way in your method you can use this to reference the “class”.

    addEvent(obj, “click”, function(e) { json.test(param1, param2, …); });

    If you don’t use an anonymous function, this will point to the clicked object. If you want to pass information from the clicked object, you can call test like:

    addEvent(obj, “click”, function(e) { json.test(this.id); });

    Or if you just want to pass the whole element, use:

    addEvent(obj, “click”, function(e) { json.test(this); });

    If you want to also pass the event, get your event in the “e” variable, then call like this:

    
    addEvent(obj, "click", function(e) {
    	if (!e) var e = window.event;
    	json.test(e, this);
    });
    
    
  125. OrbMan

    Is there a way to create objects with calculated properties where you can refer to them as myObject.myProperty instead of myObject.myProperty() ?

  126. clivemurray.com » JSON and Jack

    […] Work: Trying to get my head around JSON, and Object Oriented Javascript. Having never written a single line of OO code in any language, I’m finding the subject just a bit impenetrable at the moment. Though, on re-reading that article by Dustin just now for the third or fourth time, I started to feel a balance tip in my head towards understanding. Did you ever do those “Magic Eye” pictures, that look like a messed up pattern and then suddenly you see the page become a 3D dinosaur or whatever? It was like the first time one of those starts to “work” for you. I was reading the words over and over, and suddenly I felt part of my world view begin to change fundamentally. But then, just like when you realise that the page is becoming 3D and you involuntarily focus, losing the picture completely, my mind rebelled and thought of something else. I’m going to come back to it after lunch. Then I’m going to read it a few more times. Then I’m going to damn well try it. […]

  127. Fotiweb » Blog Archive » JavaScript Object Literal Notation

    […] A few months ago I came across a post by Dustin Diaz titled “JSON for the masses“. As some comments in the post suggest, his examples are not actually JSON (commonly used as a data interchange format) because the member names are not quoted. But the main point of the article is actually on JavaScript’s “object literal notation”, a method of creating object literals. […]

  128. Yulan

    Thank’s for this article. I hope this article can give me more infomation about json.
    if someone can help me, can you tell me the history or the maturity of json ?
    thanks’s be4.

  129. Peter Foti

    @Yulan
    Some good references:
    http://json.org/
    http://en.wikipedia.org/wiki/Json

  130. yulan

    hallo, this is yulan again.

    i want ask, can you help me, i want ask you about how to install json using neatbeans 5.0 and the steps to make web application using json in neatbeans.
    thanks

  131. Vanderbrew » Blog Archive » CSS/JS Grabbag

    […] JavaScript the JSON way - It’s pretty amazing how far the JavaScript language has come in the last few years. One of the coolest things I’ve seen recently is the technique for organizing your code with JSON to prevent function name collision and make things generally cleaner. Dustin Diaz has a great introduction to the method that will get you rolling with the JSON goodness. […]

  132. Raja

    Hi everybody
    What is wrong with the following code?

    
    function Test(month, day) {
        var months = ["","Jan", "Feb", "Mar", "...", "Nov", "Dec"];
        var getDate = {
        "Jan":["January: ","1"],
        "Feb":["February: ", "1","2", "...","29"]}
    
        var x = months[month];
        return getDate.x[0] + getDate.x[day];
    //If I change getDate.x[day] to getDate.Feb[day], then it works. But I need it dynamically
    }
    

    Thanks in advance
    Raja

  133. Shall We Zen » links for 2007-03-09

    […] JSON for the masses (tags: JSON javascript ajax tutorial programming web) […]

  134. Anthony Ettinger

    Nice explanation!

    One thing I discovered was my habit of including a “,” on the last item of a comma seperated list of objects does not work in IE or Opera (although Firefox accepts it).

    Thanks again.

  135. Bill Criswell

    Anthony Ettinger: The same thing happens in Safari. The whole time I thought I was just a total idiot. Should have just read to the last comment. =)

  136. Carter

    So I’m still not sold on the JSON-esque format over using prototype. Mainly because of prototype only defining it’s methods once vs. the JSON way of re-defining all of an object’s methods every time a new one is instantiated.

    BUT, I really like the JSON-style format because of how easy it is to comprehend, and how packaged it is like any other OOP language.

    My question is if there is anything wrong with writing “classes” like this:


    function Cat() {};
    // hold all methods/properties inside the prototype property
    // so that they only get made once no matter how many instances of Cat();
    Cat.prototype = {
    name: "",
    init: function(_name) {
    this.name = _name;
    },
    meow: function(tone) {
    if (tone = "loud") {
    var meowMsg = "MEEEOOOWWW!!!"
    } else {
    var meowMsg = "meeeoooowww.";
    }
    alert (this.name + " says: " + meowMsg);
    }
    };

    var jones = new Cat("Jones");
    jones.meow("loud");

    Seems like this is the best of both worlds, no?

  137. steph s.

    This is the third time I’ve returned to this article and telepathically praised you for writing it (hence the concrete thanks this time).

    I’m in the middle of writing some docs to help page builders get over the old way of writing js and introduce them to Object Notation in a way that won’t scare them off and the descriptions here will probably be my main resource. The way this piece is written makes it a great, reassuring intro as well as a good reference for more experienced js coders. I really appreciate the fact that you avoided using buzz-words (the term “Web 2.0″ gives me hives) and high technical/ideological jargon and instead, discuss Object Notation in a way that makes plain sense.

    Thank you!

  138. Nick

    I am agreed with JSON’s ease. If you explored YUI (Yahoo User Interface library) you can compare it’s implementations with HTML and JSON - JSON gives at least a lot of page size economy.

  139. Jayhova

    Awesome read. Just started messing with JSON. This is a great read. I may have to bounce some stuff off you One day soon.

  140. Piyush

    Thanks a lot for the great article. Its an excellent source for those who want to learn JSON.

  141. Misha's Tech Playground

    Thoughts about OOP advantage…

    Having recently refactored my JavaScript Game Engine (or what it will eventually become one) and the associated Level Editor to use OOP techniques I noticed that this has some issues besides the obvious advantages.
    Using OOP can save disk space
    In one …

  142. Ext Javascript Library for beginners, ext-perience Ext » Welcome to my Ext Blog

    […] If you’re unsure about JSON – read this […]

  143. Christopher Parker

    One of the things that confuses people when moving to object-literal notation (OLN) is accessing different properties of an OLN-based object dynamically. This is shown in Raja’s code above. The fix for this issue would be to treat the getDate object in Raja’s code as an associative array. getDate.x[day] will not work, because there is not an object named x. getDate[x][day], however, will work, because x is now being treated as a string. The following three code snippets are, therefore, equivalent:

    // Code Snippet 1
    var x = "Feb";
    alert(getDate[x][0] + getDate[x][day]);

    // Code Snippet 2
    alert(getDate[x][0] + getDate["Feb"][day]);

    // Code Snippet 3
    alert(getDate[x][0] + getDate.Feb[day]);

  144. Laolusrael

    I’ve tried all this OOP/D in JavaScript it never seems to work.
    “Nevertheless at thy word … ” I will try it again.
    I want to spend my time writing good JavaScript codes and I happen to be a guy given to reusability, so it puts me off to think i can’t use the same methods more than once a particular page.
    Dustin! I’m (should I say fed up ?) …

  145. Richard Green

    RE: Careful how you use “this”

    Hi, I must admit the ‘this’ problem is annoying, but here’s a simple way to get around the problem:

    simply wrap any event callbacks in an anonymous function, such as the following…

    Page.AddEvent(window, "load", function() { Page.Init() });

    This will correctly allow the Init function to refer to ‘this’ as the ‘Page’ object as you would expect.

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