JSON.stringify() array bizarreness with Prototype.js
The function JSON.stringify() defined in ECMAScript 5 and above (Page 201 - the JSON Object, pseudo-code Page 205), uses the function toJSON() when available on objects.
Because Prototype.js (or another library that you are using) defines an Array.prototype.toJSON() function, arrays are first converted to strings using Array.prototype.toJSON() then string quoted by JSON.stringify(), hence the incorrect extra quotes around the arrays.
The solution is therefore straight-forward and trivial (this is a simplified version of Raphael Schweikert's answer):
delete Array.prototype.toJSON
This produces of course side effects on libraries that rely on a toJSON() function property for arrays. But I find this a minor inconvenience considering the incompatibility with ECMAScript 5.
It must be noted that the JSON Object defined in ECMAScript 5 is efficiently implemented in modern browsers and therefore the best solution is to conform to the standard and modify existing libraries.
A possible solution which will not affect other Prototype dependencies would be:
var _json_stringify = JSON.stringify;
JSON.stringify = function(value) {
var _array_tojson = Array.prototype.toJSON;
delete Array.prototype.toJSON;
var r=_json_stringify(value);
Array.prototype.toJSON = _array_tojson;
return r;
};
This takes care of the Array toJSON incompatibility with JSON.stringify and also retains toJSON functionality as other Prototype libraries may depend on it.
Since JSON.stringify has been shipping with some browsers lately, I would suggest using it instead of Prototype’s toJSON. You would then check for window.JSON && window.JSON.stringify and only include the json.org library otherwise (via document.createElement('script')
…). To resolve the incompatibilities, use:
if(window.Prototype) {
delete Object.prototype.toJSON;
delete Array.prototype.toJSON;
delete Hash.prototype.toJSON;
delete String.prototype.toJSON;
}