Friday, January 18th, 2008

JSONLib: JSON Extensions a la E4X

Category: JavaScript, JSON, Library

<p>Nicholas C. Zakas wanted to keep JSON out of JavaScript. He has patterned a new form of JSON support on E4X and wrote it up.

Nichole wants:

  • The addition of two new global types: JSON and JSONList. JSON represents a JSON object while JSONList represents a JSON array.
  • Both types have a toJSONString() method that correctly encodes an object into a JSON string. The default toString() method is available but returns a string representation of the object (not a JSON string). This follows the convention set forth in E4X.
  • The [[Put]] method is overridden in both types such that it will only accept values of type JSON, JSONList, Date, boolean, string, number, or null. Any other data types cause an error to be thrown.
  • The JSON constructor allows an object to be passed in that has initial properties to add; the JSONList constructor allows an array to be passed in with items to add.
  • The typeof operator should return “json” when used on a value of type JSON or JSONList.
  • JSON strings are parsed via JSON.parse(), throwing syntax errors if they are found.

You can see it in action:

javascript
< view plain text >
  1. var obj = JSON.parse("{\"name\":\"Nicholas\",\"age\":29}");
  2.  
  3. var json = new JSON();
  4. json.put("name", "Nicholas");
  5. json.put("age", 29);
  6. var name = json.get("name");
  7. var str = json.toJSONString();
  8.  
  9. var list = new JSONList();
  10. list.put(0, "blah");
  11. list.push(25);
  12. list.push(true);
  13. var val = list.get(1);
  14. var len = list.getLength();
  15. var str = list.toJSONString();
  16.  
  17. var json = new JSON({name:"Nicholas"});
  18. var name = json.get("name");

Summary

It is slightly more verbose than the current methods for using JSON in JavaScript, however, I believe this solution keeps JSON out of the core of JavaScript and maintains useful access to JSON parsing and serialization. The key to understanding this approach is that JSON and JSONList are purely data storage objects without any additional functionality. They have one job and they do it well. Make sure you only use put() or other methods to add values to the objects instead of just assigning new properties.

Related Content:

Posted by Dion Almaer at 8:27 am
5 Comments

++---
2.2 rating from 37 votes

5 Comments »

Comments feed TrackBack URI

Not crazy about the implementation, but I do agree that rolling JSON support into ECMAscript seems dirty. I’d think HTTP would be much more of a bottleneck than JSON.js.

Comment by Steve Clay — January 18, 2008

The [[Put]] method…will only accept values of type JSON, JSONList, Date, boolean, string, number, or null.

.
Excuse me? So I can’t put an array into JSON, I have to redefine my array as a new type, JSONList? …And then it loses its identity as an array, returning typeof as JSON, making it impossible to determine the difference between key/value pairs (an object) and a value list (an array)? …And I lose my array methods, and have to deal with lists only with (a redefined in code, non-native) put and push, no pop or unshift, etc.?
.
BTW, JSON stands for JavaScript Object Notation. One can not possibly “keep JSON out of JavaScript.” JSON often needs to be sanitized or used securely, just like SQL statements or any other data exchange format.
.
I’ll take uh, JavaScript’s native support for JSON, thanks. One of the strengths of JS is that everything can be expressed as an object, and therefore basically can be translated into JSON. I only want to be forced into slow safe parsing when it’s necessary for security, not every time I define a variable with JSON.

Comment by Charles — January 18, 2008

Hi, Charles.
An valid Array is not always a valid JSON object.

For example in JavaScript:

var arr1 = [ window , document , document.body ];
var arr2 = [ 1 , {} , '3' ];

you can never call arr1.toJSONString().

Because it create a lot circular reference such as window.document.window.document.window…….which generates infinite JSONStrings.

JSON.put() should guarantee that only valid JSON type data can be set to another JSON object.

Comment by Hedger Wang — January 18, 2008

Hello Hedgar,

.I agree that putting objects inside of arrays inside of JSON can be troublesome. However, in the other direction, a valid JSON Array (or ‘JSONList’) is always a valid regular array, and I think it should be treated as such, rather than just returning typeof == ‘json’. Most of the time I create and read JSON, I don’t have to santitize it because it is internal, and I know what I’m doing.
.
Otherwise, when I’m worried about JSON input, I can use a library to parse and encode the data as I see fit. Now, I think the library should throw an error when encoding or parsing a cyclical reference as proposed in the spec, but I see no reason the ECMAScript 4 spec should include JSON over any other data format.
.
Usually it is fastest for me to translate an entire JS object into or out of JSON once, before or after transport, rather than doing a check on each individual part. JS is very fast with native objects and arrays. However if you do need a JSON object type and want to sanitize input without regex’d eval, there is this JSONLib.

Comment by Charles — January 18, 2008

All the drawbacks of XML serialization with none of the fake benefits of XML over JSON.

Comment by Andy — January 18, 2008

Leave a comment

You must be logged in to post a comment.