.toJSONString() and Object.prototype

By crisp on Monday 4 December 2006 00:21 - Comments (1)
Category: Javascript, Views: 36.186

Some time ago I had a email discussion with Douglas Crockford about .toJSONString() in the JSON JavaScript implementation. Mainly because I wrote a function-based implementation that doesn't require prototyping Object (that some people consider verboten).

My version also solved some problems with the original .toJSONString() method; first of all the matter of prototyped properties which should not be enumerated in the JSON serialized format but are when these properties are for instance of type number or string:

JavaScript:
1
2
3
Object.prototype.foo = "foo";
var a = { "bar":"bar" }
alert(a.toJSONString());



This yields {"bar":"bar","foo":"foo"} in the original version but technically should have left out the 'foo'-property. Offcourse this is an example that uses 'verboten' prototype on Object, but still...

Second problem is this:

JavaScript:
1
2
var a = new String("foo");
alert(a.toJSONString());



Depending on the javascript implementation this yields {"0":"f","1":"o","2":"o"} or {}. Now indeed when using a constructor like this the result is of type object, but it's constructor is still String so I think it should be handled as a string-object instead of as an arbitrary object. The original version fails to deal with that.

The last problem I solved by using a switch on the constructor instead of using typeof. As to problem number 1, I solved that in my version by using the hasOwnProperty() method. Unfortunately this method is not supported by some older browsers, but ofcourse this can easily be remedied by backporting it... using Object.prototype:

JavaScript:
1
2
3
4
5
6
if (!Object.prototype.hasOwnProperty)
    Object.prototype.hasOwnProperty = function(p)
    {
        var undefined;
        return this.constructor.prototype[p] === undefined;
    }



So much for 'verboten' I thought and then I started thinking that there are some very valid reasons for prototyping Object, especially when it comes to adding methods to Object that are standardized but not available in older javascript implementations.
Now that .toJSONString() will probably be standardized in future javascript implementations I think it is pretty much OK to extend Object for current and older javascript implementations. My stance now is that scripts that fail to deal with prototyped methods or properties on Object are just as bad as using prototype on Object for unnecessary reasons (in which case it is still 'verboten').

With that in mind I wrote a second version of .toJSONString() that also has some performance-improvements over the original version and is therefor also somewhat larger.

Now my script still may not pass the scrutiny of Douglas' JSON specification, especially because I added undefined, NaN and Infinity, but at least I hope this post gives some food for thought about several matters including the spec itself and the current inability of the javascript JSON implementation of being a means to validate the spec; basically and ideally (when not using objects that are not part of the spec) this should always be true:

JavaScript:
1
someobject === someobject.toJSONString().parseJSON();

Volgende: The useless javascript: pseudo-protocol 12-'06 The useless javascript: pseudo-protocol
Volgende: Capability detection - the better way 12-'06 Capability detection - the better way

Comments


By Adam, Friday 29 May 2009 19:58

"This should always be true: someobject === someobject.toJSONString().parseJSON();"

I could not agree more!

Sincerely,
-Adam

Comments are closed