JSON格式化方式
- 通过【正则对字符串进行解析】来进行JSON格式化;【正则实现 | 格式化JSON String】
- 通过【JSON.stringify】原生方法实现JSON格式化;【JSON API实现 | 格式化JSON String】
- 通过【JSON拼接】实现JSON格式化;【本篇文章】
实现思路
非常惭愧的说,这个实现方式是在我看了JSON.stringify在MDN上的Polyfill方法之后,在他的方法基础上实现的格式化方法。其原理就是递归遍历JSON,对JSON的每一项进行格式化。另外,与上一篇正则实现JSON格式化不同,这篇增加了缩进符号的自定义,缩进符号可以通过参数的形式穿进去,无论是使用制表符还是2空格,4空格,都可以方便的实现。(目前最好用的还是JSON.stringify原生的格式化方法哈,参数值的种类更丰富)
后面我会继续研究更优秀更全面兼容性更好的格式化方法。例如json.cn
的格式化方法,js原生
的格式化方法等。
字符串处理与转化JSON对象
/*
param1 JSONstr 未格式化的JSON字符串
return 转化后的JSON对象
*/
function getJSONObj(JSONstr) {
let JSONObj;
try {
JSONstr = JSONstr.replace(/'/g, '"');
JSONObj = JSON.parse(JSONstr)
} catch (error) {
// 转换失败错误提示
console.error('json数据格式有误...');
console.error(error);
JSONObj = 'Invalid value';
}
return JSONObj;
}
JSON格式化
const format = (function formatJSON() {
// 用于转化字符串中的空字符和特殊字符
let escMap = {'"': '\\"', '\\': '\\\\', '\b': '\\b', '\f': '\\f', '\n': '\\n', '\r': '\\r', '\t': '\\t'};
let escFunc = function (m) { return escMap[m] || '\\u' + (m.charCodeAt(0) + 0x10000).toString(16).substr(1); };
let escRE = /[\\"\u0000-\u001F\u2028\u2029]/g;
return function (JSONObj, space, time = 1) {
if (JSONObj === null) {
return 'null';
} else if (typeof JSONObj === 'number') {
return isFinite(JSONObj) ? JSONObj.toString() : 'null';
} else if (typeof JSONObj === 'boolean') {
return JSONObj.toString();
} else if (typeof JSONObj === 'object') {
if (typeof JSONObj.toJSON === 'function') {
return format(JSONObj.toJSON(), space, time);
} else if (JSONObj.constructor === Array) {
var res = '[';
for (var i = 0; i < JSONObj.length; i++)
res += (i ? ', ' : '') + format(JSONObj[i], space, time);
return res + ']';
} else if (JSONObj.constructor === Object) {
let wordIndent = '\n' + space.repeat(time);
let wordWrap = '\n' + space.repeat(time - 1);
time++;
var tmp = [];
for (var k in JSONObj) {
if (JSONObj.hasOwnProperty(k)) {
tmp.push(format(k, space, time) + ': ' + format(JSONObj[k], space, time));
}
}
return '{' + wordIndent + tmp.join(',' + wordIndent) + wordWrap +'}';
}
} else {
return '"' + JSONObj.toString().replace(escRE, escFunc) + '"';
}
}
})()
以上格式化代码中,进行JSON拼接
格式化的逻辑主要是以下部分:从外而内进行JSON格式化。每向内递归一层time加1。是不是比正则那一篇的方式更简洁清晰呢?
let wordIndent = '\n' + space.repeat(time);
let wordWrap = '\n' + space.repeat(time - 1);
time++;
var tmp = [];
for (var k in JSONObj) {
if (JSONObj.hasOwnProperty(k)) {
tmp.push(format(k, space, time) + ': ' + format(JSONObj[k], space, time));
}
}
return '{' + wordIndent + tmp.join(',' + wordIndent) + wordWrap +'}';
demo
可以点击这里进行测试,欢迎拍砖!