[转帖]Mootools源码分析-25 -- JSON
原帖地址:http://space.flash8.net/space/?uid-18713-action-viewspace-itemid-404546
原作者:我佛山人
//JSON其实就是JS里结构良好的键-值对对象,比XML更轻量,
//并且不需要特别的解释引擎,因此更适合用于Web上的前后端通信,
//有关JSON的资料,可以参考:http://www.json.org
//对象JSON化的编码与解码
var JSON = new Hash({
//将JSON对象数据编码
encode: function(obj) {
//根据对象类型分别转换
switch ($type(obj)) {
//字符串
case 'string':
//替换ansi码为0~31的特殊字符
return '"' + obj.replace(/[\x00-\x1f\\"]/g, JSON.$replaceChars) + '"';
//数组
case 'array':
//对数组的每一项编码,再过滤掉编码后为空的项
return '[' + String(obj.map(JSON.encode).filter($defined)) + ']';
//键-值的数据
case 'object': case 'hash':
var string = [];
//遍历
Hash.each(obj, function(value, key) {
var json = JSON.encode(value);
//只需要值编码不为空时的项
if (json) string.push(JSON.encode(key) + ':' + json);
});
return '{' + string + '}';
//对数字和布尔类型,直接转为字符串
case 'number': case 'boolean': return String(obj);
//除以上情况都为非法
case false: return 'null';
}
return null;
},
//需要两次转义的特殊字符
$specialChars: {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\'},
//替换需要转义的特殊字符
$replaceChars: function(chr) {
//如果特殊字符不在上面的列表中,转为unicode码表示
return JSON.$specialChars[chr] || '\\u00' + Math.floor(chr.charCodeAt() / 16).toString(16) + (chr.charCodeAt() % 16).toString(16);
},
//解码
decode: function(string, secure) {
//只有非空字符串才需要解码
if ($type(string) != 'string' || !string.length) return null;
//如果secure为true,要求是严格的JSON格式,比如{"a":"b", "c" : 2}而不是{'a' : 'b', c : 2}
if (secure && !(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(string.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''))) return null;
return eval('(' + string + ')');
}
});
//为四种类型提示toJSON方法的实现
Native.implement([Hash, Array, String, Number], {
toJSON: function() {
return JSON.encode(this);
}
});
//并且不需要特别的解释引擎,因此更适合用于Web上的前后端通信,
//有关JSON的资料,可以参考:http://www.json.org
//对象JSON化的编码与解码
var JSON = new Hash({
//将JSON对象数据编码
encode: function(obj) {
//根据对象类型分别转换
switch ($type(obj)) {
//字符串
case 'string':
//替换ansi码为0~31的特殊字符
return '"' + obj.replace(/[\x00-\x1f\\"]/g, JSON.$replaceChars) + '"';
//数组
case 'array':
//对数组的每一项编码,再过滤掉编码后为空的项
return '[' + String(obj.map(JSON.encode).filter($defined)) + ']';
//键-值的数据
case 'object': case 'hash':
var string = [];
//遍历
Hash.each(obj, function(value, key) {
var json = JSON.encode(value);
//只需要值编码不为空时的项
if (json) string.push(JSON.encode(key) + ':' + json);
});
return '{' + string + '}';
//对数字和布尔类型,直接转为字符串
case 'number': case 'boolean': return String(obj);
//除以上情况都为非法
case false: return 'null';
}
return null;
},
//需要两次转义的特殊字符
$specialChars: {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\'},
//替换需要转义的特殊字符
$replaceChars: function(chr) {
//如果特殊字符不在上面的列表中,转为unicode码表示
return JSON.$specialChars[chr] || '\\u00' + Math.floor(chr.charCodeAt() / 16).toString(16) + (chr.charCodeAt() % 16).toString(16);
},
//解码
decode: function(string, secure) {
//只有非空字符串才需要解码
if ($type(string) != 'string' || !string.length) return null;
//如果secure为true,要求是严格的JSON格式,比如{"a":"b", "c" : 2}而不是{'a' : 'b', c : 2}
if (secure && !(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(string.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, ''))) return null;
return eval('(' + string + ')');
}
});
//为四种类型提示toJSON方法的实现
Native.implement([Hash, Array, String, Number], {
toJSON: function() {
return JSON.encode(this);
}
});