JSON for the masses
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
initfunction. - 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.

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!












February 19th, 2006 at 3:10 am
I used this scrollerscript once for a project:
Here is a part of it - is this good coding practise:
// edited by author
February 19th, 2006 at 5:46 am
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
February 19th, 2006 at 10:59 am
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.
February 19th, 2006 at 12:19 pm
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.
February 19th, 2006 at 1:21 pm
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.
February 19th, 2006 at 1:52 pm
Very nice article, thanks for writing it.
February 19th, 2006 at 1:57 pm
Spell it with me: W-e-e-k-e-n-d.
:-) (still reading - eyes sore)
February 19th, 2006 at 2:15 pm
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.
February 19th, 2006 at 2:31 pm
@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.
February 19th, 2006 at 3:52 pm
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.
February 19th, 2006 at 4:07 pm
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.
February 19th, 2006 at 4:13 pm
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…
February 19th, 2006 at 9:12 pm
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.
February 19th, 2006 at 10:16 pm
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.
February 20th, 2006 at 12:07 am
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
February 20th, 2006 at 12:09 am
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.
February 20th, 2006 at 1:10 am
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.
February 20th, 2006 at 1:34 am
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! :-)
February 20th, 2006 at 3:10 am
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.
February 20th, 2006 at 6:19 am
[…] Dustin Diaz - JSON For the Masses […]
February 20th, 2006 at 8:40 am
Can you add examples of functions which take paramaters? Thanks.
February 20th, 2006 at 10:04 am
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.
February 20th, 2006 at 10:38 am
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).
February 20th, 2006 at 12:07 pm
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.)
February 20th, 2006 at 12:13 pm
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! :)
February 20th, 2006 at 12:24 pm
[…] » JSON for the masses (tags: javascript Programming) […]
February 20th, 2006 at 1:20 pm
With all the confusion, I may just be tempted to change the name of the article to “Object Notation for the masses.”
February 20th, 2006 at 1:29 pm
Dustin, this is a great article, please give more examples or code snippets of this used properly.
February 20th, 2006 at 2:29 pm
@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!
February 20th, 2006 at 5:09 pm
[…] » JSON for the masses (categories: javascript webdev ) […]
February 20th, 2006 at 5:09 pm
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;
}
February 20th, 2006 at 5:33 pm
[…] JSON for the masses (tags: programming) […]
February 20th, 2006 at 6:03 pm
Lap,
You could do so like this:
February 20th, 2006 at 6:46 pm
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?
February 20th, 2006 at 7:21 pm
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;
}
};
February 20th, 2006 at 7:23 pm
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…
February 20th, 2006 at 7:30 pm
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.
February 20th, 2006 at 8:50 pm
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 ;)
February 20th, 2006 at 8:51 pm
Here’s a pretty helpful intro to OO Javascript, btw:
http://www.javascriptkit.com/javatutors/oopjs.shtml
February 20th, 2006 at 9:23 pm
[…] JSON for the masses (tags: javascript json) […]
February 20th, 2006 at 9:38 pm
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
February 20th, 2006 at 9:53 pm
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.
February 20th, 2006 at 11:31 pm
It means that we cannot use JSON to instantiate object? is it correct? So, we cannot use JSON to write a class in javascript?
February 21st, 2006 at 5:28 am
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.
February 21st, 2006 at 5:34 am
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. ;)
February 21st, 2006 at 5:53 am
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
February 21st, 2006 at 9:17 am
[…] 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. […]
February 21st, 2006 at 10:47 am
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.
February 21st, 2006 at 2:02 pm
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.
February 22nd, 2006 at 12:38 am
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”
February 22nd, 2006 at 3:49 pm
Normal functions can be objects too..
function Person(name){
this.name = name;
}
var firstPerson = new Person(”John”);
var secondPerson = new Person(”Dustin”);
…
February 23rd, 2006 at 8:09 am
[…] 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. • • • […]
February 23rd, 2006 at 12:55 pm
[…] 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. […]
February 23rd, 2006 at 11:09 pm
[…] 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). […]
February 24th, 2006 at 7:17 pm
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!
February 27th, 2006 at 10:44 am
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.
March 1st, 2006 at 1:21 pm
what about constructors, prototype and nested objects
March 3rd, 2006 at 5:40 am
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.
March 3rd, 2006 at 6:18 am
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
March 4th, 2006 at 6:23 pm
Good work Dustin, alot of useful information.
Thanks,
Raj
March 6th, 2006 at 5:42 am
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..
March 6th, 2006 at 12:36 pm
function Person(height, weight) {
this.height = height;
this.weight = weight;
}
Person.prototype = {
getHeight: function () {
return this.height;
},
getWeight: function () {
return this.weight;
}
}
March 9th, 2006 at 8:18 pm
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.
March 18th, 2006 at 1:51 pm
[…] 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. […]
March 22nd, 2006 at 9:07 am
what is the disadvantage of following notation?
function Class1() {
var prop1 = 1;
this.method1 = function() {
return 1 + prop1;
}
}
March 26th, 2006 at 10:23 am
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!
April 5th, 2006 at 1:18 am
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
April 11th, 2006 at 2:14 am
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
May 22nd, 2006 at 11:10 pm
[…] 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. […]
May 24th, 2006 at 2:21 am
[…] 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.” […]
May 25th, 2006 at 12:37 am
[…] 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… […]
May 25th, 2006 at 3:54 am
[…] 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: […]
May 25th, 2006 at 10:22 am
[…] 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): […]
May 27th, 2006 at 3:10 am
[…] 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: […]
May 31st, 2006 at 9:09 pm
I’m new to JSON concept, can anyone help me out how JSON work & how to install it!
June 1st, 2006 at 2:01 am
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
June 1st, 2006 at 10:34 am
[…] 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): […]
June 15th, 2006 at 5:01 am
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
June 21st, 2006 at 4:59 am
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? :-(
June 21st, 2006 at 9:18 am
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.
June 27th, 2006 at 6:23 am
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.
June 27th, 2006 at 9:23 am
Hi Russ, re-read the section where I talked about the “this” keyword in the article.
July 4th, 2006 at 1:18 am
I think you’ve got some voodoo going on with your initializer and inializer in your last block of code ;)
July 4th, 2006 at 11:30 pm
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.
July 5th, 2006 at 2:26 am
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.
July 7th, 2006 at 8:22 pm
[…] 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: […]
July 8th, 2006 at 9:24 am
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. :]
July 11th, 2006 at 1:40 pm
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
July 13th, 2006 at 7:42 pm
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.
July 14th, 2006 at 10:09 am
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 ?
August 1st, 2006 at 6:37 am
[…] 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: […]
August 10th, 2006 at 10:17 am
Hi Dustin
Very useful information, it appears it will be quite useful for me. I’ll try to find more about it.
August 28th, 2006 at 2:22 pm
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:
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.
August 29th, 2006 at 3:17 am
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 ?
August 30th, 2006 at 7:16 am
@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 } } }August 30th, 2006 at 7:22 am
@Peter:
Forgot to say
August 30th, 2006 at 7:34 am
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.
August 30th, 2006 at 7:34 am
@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}August 30th, 2006 at 7:38 am
@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!
August 30th, 2006 at 7:38 am
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.
August 30th, 2006 at 7:39 am
Hehehe… did it again. :)
August 31st, 2006 at 1:28 am
@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;iAugust 31st, 2006 at 1:29 am
@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");August 31st, 2006 at 1:31 am
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");August 31st, 2006 at 5:00 am
@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)August 31st, 2006 at 7:56 am
Published an article about it:
http://www.thomasfrank.se/classier_json.html
August 31st, 2006 at 9:14 am
@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.
August 31st, 2006 at 9:53 am
Oh, I see you posted again… I’ll go read your article now.
August 31st, 2006 at 12:21 pm
@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 ;-).
August 31st, 2006 at 12:49 pm
@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.
September 1st, 2006 at 12:07 am
@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.
September 1st, 2006 at 3:13 am
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 };September 1st, 2006 at 6:59 am
@Thomas
Mind if I ask what tool you’re using for speed tests and memory usage?
September 1st, 2006 at 7:14 am
@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.
September 1st, 2006 at 8:25 am
@Thomas
Simple is good. :-)
September 2nd, 2006 at 2:30 pm
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 ?
September 3rd, 2006 at 2:39 am
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 }September 3rd, 2006 at 3:16 am
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 }September 3rd, 2006 at 3:48 am
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
September 3rd, 2006 at 4:29 am
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
September 3rd, 2006 at 5:04 am
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
September 18th, 2006 at 2:48 pm
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()September 28th, 2006 at 7:50 am
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
October 16th, 2006 at 2:16 pm
@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:
November 3rd, 2006 at 2:31 pm
Is there a way to create objects with calculated properties where you can refer to them as myObject.myProperty instead of myObject.myProperty() ?
November 29th, 2006 at 3:24 am
[…] 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. […]
December 13th, 2006 at 3:46 pm
[…] 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. […]
December 19th, 2006 at 7:36 pm
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.
December 20th, 2006 at 8:40 am
@Yulan
Some good references:
http://json.org/
http://en.wikipedia.org/wiki/Json
January 3rd, 2007 at 7:31 pm
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
February 7th, 2007 at 10:57 pm
[…] 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. […]
February 15th, 2007 at 8:40 am
Hi everybody
What is wrong with the following code?
Thanks in advance
Raja
March 9th, 2007 at 10:47 am
[…] JSON for the masses (tags: JSON javascript ajax tutorial programming web) […]
March 26th, 2007 at 9:44 am
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.
April 12th, 2007 at 7:47 am
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. =)
May 22nd, 2007 at 2:37 pm
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?
July 18th, 2007 at 11:57 am
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!
August 8th, 2007 at 7:44 am
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.
September 29th, 2007 at 1:13 pm
Awesome read. Just started messing with JSON. This is a great read. I may have to bounce some stuff off you One day soon.
October 31st, 2007 at 4:42 pm
Thanks a lot for the great article. Its an excellent source for those who want to learn JSON.
December 4th, 2007 at 10:15 am
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 …
February 10th, 2008 at 5:20 pm
[…] If you’re unsure about JSON – read this […]
February 19th, 2008 at 12:59 pm
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 1var x = "Feb";
alert(getDate[x][0] + getDate[x][day]);
// Code Snippet 2alert(getDate[x][0] + getDate["Feb"][day]);
// Code Snippet 3alert(getDate[x][0] + getDate.Feb[day]);
March 1st, 2008 at 2:48 pm
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 ?) …
April 25th, 2008 at 3:50 am
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.