I need to use:
JSON.stringify()
which should be supported by Chrome, Safari, and Firefox. I think IE8 also has support for the JSON object.
You don't need to use conditionals to determine whether to include json2.js or not. Take a look at the source code:
var JSON;
if (!JSON) {
JSON = {};
}
if (typeof JSON.stringify !== 'function') {
JSON.stringify = function (value, replacer, space) {
// Code
}
}
if (typeof JSON.parse !== 'function') {
JSON.parse = function (text, reviver) {
// Code
}
}
What this does is first check to see if JSON
already exists as an object. If not, then it creates a new object to house the JSON functions. Then, it checks for a native implementation of .stringify()
or .parse()
exist. If not, then it creates those functions.
Bottom line: if a native implementation exists, including json2.js
will not overwrite the native implementation. Otherwise, it'll add that functionality, so there's no reason you need to use conditionals, unless you are trying to minimize requests.
(It might also be noted that IE10 does not support conditional statements, so I'd recommend against relying on them unless there isn't any alternative.)
Just to follow up Mozilla has made a polyfill for the JSON object if you need it to work in IE compatibility mode.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON
if (!window.JSON) {
window.JSON = {
parse: function(sJSON) { return eval('(' + sJSON + ')'); },
stringify: (function () {
var toString = Object.prototype.toString;
var isArray = Array.isArray || function (a) { return toString.call(a) === '[object Array]'; };
var escMap = {'"': '\\"', '\\': '\\\\', '\b': '\\b', '\f': '\\f', '\n': '\\n', '\r': '\\r', '\t': '\\t'};
var escFunc = function (m) { return escMap[m] || '\\u' + (m.charCodeAt(0) + 0x10000).toString(16).substr(1); };
var escRE = /[\\"\u0000-\u001F\u2028\u2029]/g;
return function stringify(value) {
if (value == null) {
return 'null';
} else if (typeof value === 'number') {
return isFinite(value) ? value.toString() : 'null';
} else if (typeof value === 'boolean') {
return value.toString();
} else if (typeof value === 'object') {
if (typeof value.toJSON === 'function') {
return stringify(value.toJSON());
} else if (isArray(value)) {
var res = '[';
for (var i = 0; i < value.length; i++)
res += (i ? ', ' : '') + stringify(value[i]);
return res + ']';
} else if (toString.call(value) === '[object Object]') {
var tmp = [];
for (var k in value) {
if (value.hasOwnProperty(k))
tmp.push(stringify(k) + ': ' + stringify(value[k]));
}
return '{' + tmp.join(', ') + '}';
}
}
return '"' + value.toString().replace(escRE, escFunc) + '"';
};
})()
};
}
A shiv just createElement
's the HTML5 elements. It has nothing to do with JSON. Try getting an actual JSON parser like json2.js from Crockford.
There's a better solution...
This doesn't directly answer your question, it provides a complete solution to your problem instead.
The jquery-json library provides a wrapper that uses the native JSON object implementation if it's available and falls back to it's own JSON implementation if it isn't. Meaning it'll work in any browser.
Here's the Usage Example from the Project's home page:
var thing = {plugin: 'jquery-json', version: 2.3};
var encoded = $.toJSON( thing );
// '{"plugin":"jquery-json","version":2.3}'
var name = $.evalJSON( encoded ).plugin;
// "jquery-json"
var version = $.evalJSON(encoded).version;
// 2.3
The usage is very simple: toJSON stringifies the JS source; evalJSON converts JSON string data back to JavaScript objects.
Of you look at the source, the implementation is surprisingly simple but it works very well. I have used it personally in a few projects.
There's no need to do browser detection if it works in every browser.
To answer the question in the title directly, yes IE8 supports JSON.stringify()
natively.
IE8 is the first version of IE to get this support, and the functionality is explained in detail by the dev team here: http://blogs.msdn.com/b/ie/archive/2008/09/10/native-json-in-ie8.aspx
The answer the second part of the question, yes you would need to include alternate functionality for IE6/IE7. Something like Modernizr can make it easy to check this.
Also note if the user is in Compatibility View in IE8, the JSON object will not be available.
put following code in your js file ;
var JSON = JSON || {};
// implement JSON.stringify serialization
JSON.stringify = JSON.stringify || function (obj) {
var t = typeof (obj);
if (t != "object" || obj === null) {
// simple data type
if (t == "string") obj = '"'+obj+'"';
return String(obj);
}
else {
// recurse array or object
var n, v, json = [], arr = (obj && obj.constructor == Array);
for (n in obj) {
v = obj[n]; t = typeof(v);
if (t == "string") v = '"'+v+'"';
else if (t == "object" && v !== null) v = JSON.stringify(v);
json.push((arr ? "" : '"' + n + '":') + String(v));
}
return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}");
}
};
// implement JSON.parse de-serialization
JSON.parse = JSON.parse || function (str) {
if (str === "") str = '""';
eval("var p=" + str + ";");
return p;
};