If you've done any web development in recent years, you've no doubt heard about JSON (typically pronounced like the name "Jason") and have likely used it in your projects whether or not you realize it. The acronym stands for JavaScript Object Notation, and as you can guess, it deals with describing JavaScript objects. But what is it, and why does it matter so much to us as web developers?

Squares and rectangles

There's a mathematical statement that all squares are rectangles, but not all rectangles are squares. The same principle applies to JSON and JavaScript. All JSON documents are valid JavaScript objects. However, not all JavaScript objects are valid JSON documents.

JSON is the JavaScript equivalent of an XML document, basically. It's a way of serializing an object's attributes - it's data - in to a document format that can be transported through the interwebs and used by browsers, back-end systems, and everything else in between and around. JSON just happens to use JavaScript as it's document format.

Note that the language I'm using is critical, as well. It's not a "JSON object", and it's not a "JavaScript Document". I am explicitly saying "JSON document" because that's what it is - a document in the same way XML is a document.

Versatility

JSON is quite the versatile little document format. Developers tend to use JSON as a direct replacement for XML based AJAX calls - making the name AJAX ("Asynchronous JavaScript And XML") a bit of a misnomer - but who wants to says "AJAJ"? ... or "AJAJs"?

So-called "document" or "document-oriented" database systems like MongoDB, CouchDB and RavenDB (to name only a few) use JSON documents as their primary format for data storage and retrieval. There are countless other uses for JSON documents as well, including configuration files for package managers like NPM, build tools like GruntJS and more.

It's the little-document format that could, but it can make or break your applications if you get the document format wrong with something as simple as leaving an extra , in place.

The document format

At it's core, JSON documents are a description of data with key-value pairs where the key is always a quoted string, and the value can be any of a number of things: strings, numbers, boolean values, other JSON objects, and more. JSON is a strict document format, too. One small mistake (like the extra comma I already mentioned) and your document won't be valid.

It can be rather easy to get lost in the JSON format when you're first starting. Being a strict format means there are a lot of rules to follow. Fortunately there are a few rules you can stick to initialy, and you will generally be safe in your documents. Eventually you'll start running in to the edge cases and invalid document entries, but hopefully by that time you'll have a better understanding of JSON as a document format and be able to figure out the problem quickly.

The core list of rules that I keep in mind when working with JSON is as follows:

Open and close { } curly braces to denote the document

curly braces to denote the document Use "key": value pairs to describe everything

pairs to describe everything All "keys" are quoted with double quotes (yes, this is a strict double-quote requirement)

Values cannot be code / functions

No trailing ,

Here's an example of a valid JSON document:

Sample JSON Document { "foo": "bar", "baz": 1, "quux": true, "widget": { "wombat": true, "that thing": "I sent you" } }

It's easy to think that this is a JavaScript object literal - because it is. You can copy & paste this in to your JavaScript code, assign it to a variable, and start accessing attributes from it. But remember that not all JavaScript is valid JSON.

Not a JSON Document { foo: "bar", baz: 1, "quux": true, 'widget': { "wombat": true, "that thing": "I sent you" }, }

This example is not a valid JSON document, even though it's a perfectly valid JavaScript object. There are three separate problems with this object definition, that prevent it from being a JSON document:

Unquoted keys A Single-quote key A trailing comma after widget

Many projects that support JSON documents will be rather forgiving of this object trying to masquerade as JSON, but most won't. For your own safety and sanity, then, it is beter to always be strict in your use of JSON than to have to hunt down strange bugs somewhere in your software systems.

(For a complete listing of all possible values for JSON documents, see the JSON standard website.)

Working with JSON for fun and profit

The good news, even with all the idiosyncracies of getting a JSON document formatted exactly right, is that we don't have to deal with it directly most of the time. Browser based tools that use JSON, widgets and control suites like Kendo UI, back-end servers and everythign in between have all automated this for us under the guidance of the JSON standard.

There are two primary methods that we need to be aware of when working with JSON, and every major browser supports these methods at this point.

JSON.stringify(object)

(object).toJSON

If you happen to be supporting old browsers, though, don't worry too much. You can grab the json2.js library from Douglas Crockford - the father of the JSON standard - and provide the same capabilities in old browswers. Or, if you're using Kendo UI, you can use the built in kendo.stringify method. It provides the same shim that json2.js does, but it's built in to Kendo UI so you don't have to grab yet another file.

JSON.stringify

The first method, JSON.stringify is responsible for converting an object in to a JSON document. It reads through the object using the process set forth by the JSON standard and creates all of the appropriate {"key": "value"} pairs in the resulting documenting. This is the method that most tool set, like Kendo UI, call when they are converting an object to a JSON document.

It's easy to demonstrate JSON.stringify as well. Open a JavaScript console in FireBug, Firefox developer tools, the Chrome developer tools, or any other browser and type the following:

JSON.stringify({a: "b"})

The result should be:

{"a": "b"}

(though your specific browser console may return this wrapped in an additional layer of " quotes)

You can try this with any object and see the results quite easily. The stringify method will serialize any JavaScript object, though it may not always produce the results that you want or expect.

(object).toJSON

There will inevitably be times where you need some data to exist on an object in the browser, but don't want that data to be sent back to a server when it is converted in to a JSON document for an AJAX call. You may also need to inject some data, or pre-process some data to make the server happy. Well, good news again! We can very easily customize the data that is produced by the stringify method when passing in our objects. We only need to provide a toJSON method on the object in question.

Open your favorite JavaScript console again, and type (copy & paste) this:

Override toJSON var obj = { foo: "bar", baz: "quux", toJSON: function(){ return {a: "b"}}}; JSON.stringify(obj);

The result will be the same {"a": "b"} that we saw before! Even though this object has a "foo" and "bar" attribute, and does not directly contain an "a" attribute, we have told the JSON.stringify process to use a set of data that is different from what the object actually has available. When JSON.stringify is called, it looks for the presence of a .toJSON method and if that method exists, it calls that method instead of running the standard process to serialize the object.

There's one important and interesting note here, as well. Did you notice that the toJSON method I provided does not return a valid JSON document? This is because the toJSON method only has to return a valid JavaScript object that will be converted to a JSON document. The stringify method will handle the output of the toJSON method instead of the original target object, resulting in the data we want to be serialized, being serialized.

There are a lot more tricks that the JSON standard and the stringify and toJSON methods can perform, though. For a good read on some of these tricks and trip-ups, check out Jim Cowart's blog post on What You Might Not Know About JSON.stringify().

JSON is your friend - play nice