JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,由于其简洁、可读性高和易于解析等特点,现已成为前端开发中最常用的数据传输格式。然而,一个好的 JSON 数据阅读器可以让数据的结构和内容更加清晰易读,提高开发效率。接下来,我们将以打造一个完美的 JSON 阅读器为例,来阐述如何从多个方面进行设计和优化。
一、解析JSON数据
如何解析JSON数据一般有两种方式:直接使用eval()
函数和使用JSON对象的parse()
方法。eval()
函数可以将任何JavaScript代码字符串解析为可执行的代码,在解析非简单JSON数据时会带来潜在的安全风险。因此,我们建议使用JSON对象的parse()
方法进行JSON数据的解析。
const jsonStr = '[{"name": "John", "age": 35}, {"name": "Alex", "age": 25}]';
const jsonArray = JSON.parse(jsonStr); // 解析JSON字符串为数组
console.log(jsonArray); // [{name: "John", age: 35}, {name: "Alex", age: 25}]
在此基础上,我们可以对解析后的 JSON 数据进行遍历和操作,方便地将其展示到页面上。
二、格式化JSON数据
当 JSON 数据非常大且嵌套层次很深时,其格式化后的展示可以更加清晰易读。在展示 JSON 数据时,我们可以为其添加缩进和换行符等视觉分隔符,以达到更好的阅读效果。
const jsonStr = `{
"name": "John",
"age": 35,
"isMarried": true,
"hobbies": [
"reading",
"swimming",
"cooking"
],
"address": {
"street": "123 Main St",
"city": "New York",
"state": "NY",
"zip": 10001
}
}`;
const jsonFormatted = JSON.stringify(JSON.parse(jsonStr), null, 2); // 第二个参数为格式化选项
console.log(jsonFormatted);
/* 输出结果
{
"name": "John",
"age": 35,
"isMarried": true,
"hobbies": [
"reading",
"swimming",
"cooking"
],
"address": {
"street": "123 Main St",
"city": "New York",
"state": "NY",
"zip": 10001
}
}
*/
三、展开/折叠JSON数据
在 JSON 数据非常大或者嵌套层次很深时,我们可以提供展开/折叠功能,以方便用户查看和操作数据。
// 使用递归方式遍历JSON数据,增加展开/折叠功能
function render(jsonObj, level) {
let html = '';
for(let key in jsonObj) {
const value = jsonObj[key]; // value可能为对象或数组
const valueType = Object.prototype.toString.call(value);
html += `
<div class="level-${level}">
<span class="key">${key}:</span>`;
if(valueType === '[object Object]') {
html += '<span class="value object">{' + render(value, level+1) + '}</span>';
} else if(valueType === '[object Array]') {
html += '<span class="value array">[';
for(let i=0; i < value.length; i++) {
const item = value[i];
const itemType = Object.prototype.toString.call(item);
if(itemType === '[object Object]') {
html += "<span class='value object'>{" + render(item, level+1) + "}";
} else {
html += `<span class="value">${item}</span>`;
}
}
html += ']';
} else {
html += `<span class="value">${value}</span>`;
}
html += `
</div>`;
}
return html;
}
四、搜索JSON数据
在数据非常大时,提供搜索功能可以大幅度提高查找效率。我们可以为 JSON 阅读器增加搜索输入框,在用户输入关键词后对 JSON 数据进行筛选,并高亮显示匹配的结果。
const jsonStr = '{"name": "John", "age": 35, "hobbies": ["reading", "swimming", "cooking"]}';
const jsonObj = JSON.parse(jsonStr);
const searchKey = 'swimming';
function search(jsonObj, searchKey) {
let matchArr = [];
for(let key in jsonObj) {
const value = jsonObj[key];
const valueType = Object.prototype.toString.call(value);
if(valueType === '[object Object]') {
matchArr = matchArr.concat(search(value, searchKey)); // 递归搜索
} else if(valueType === '[object Array]') {
for(let i=0; i < value.length; i++) {
const item = value[i];
const itemType = Object.prototype.toString.call(item);
if(itemType === '[object Object]') {
matchArr = matchArr.concat(search(item, searchKey)); // 递归搜索
} else if(itemType === '[object String]' && item.includes(searchKey)) {
matchArr.push(item);
}
}
} else if(valueType === '[object String]' && value.includes(searchKey)) {
matchArr.push(value);
}
}
return matchArr;
}
const matchArr = search(jsonObj, searchKey);
console.log(matchArr); // ["swimming"]
五、展示JSON数据类型
在 JSON 数据显示时,我们可以为不同类型的数据添加不同的标识或者图标,以方便用户快速识别和理解它。
// 在 render() 函数中添加数据类型判断
function render(jsonObj, level) {
let html = '';
for(let key in jsonObj) {
const value = jsonObj[key];
const valueType = Object.prototype.toString.call(value);
html += `
<div class="level-${level}">
<span class="key">${key}:</span>`;
if(valueType === '[object Object]') {
html += '<span class="value object-icon">{' + render(value, level+1) + '}</span>';
} else if(valueType === '[object Array]') {
html += '<span class="value array-icon">[';
for(let i=0; i < value.length; i++) {
const item = value[i];
const itemType = Object.prototype.toString.call(item);
if(itemType === '[object Object]') {
html += "<span class='value object-icon'>{" + render(item, level+1) + "}";
} else {
html += `<span class="value">${item}</span>`;
}
}
html += ']';
} else if(valueType === '[object String]') {
html += `<span class="value string-icon">${value}</span>`;
} else if(valueType === '[object Number]') {
html += `<span class="value number-icon">${value}</span>`;
} else if(valueType === '[object Null]'){
html += `<span class="value null-icon">null</span>`;
} else if(valueType === '[object Boolean]') {
html += `<span class="value boolean-icon">${value}</span>`;
}
html += `
</div>`;
}
return html;
}
六、JSON压缩
对于非常大的 JSON 数据,我们可以提供压缩功能,将其压缩为一条单行显示,从而节约页面空间。
function compress(jsonStr) {
return jsonStr.replace(/\s+/g, ''); // 去掉所有空格、制表符和换行符
}
在最终的展示结果中,我们可以给用户提供切换格式化/压缩显示的功能。 以上是我们设计完美的 JSON 阅读器时需要考虑的一些方面。不同需求的网站,可能会对这些方面的优先级和实现方式有所不同。但总体来说,我们应该将用户的体验放在首位,考虑这些功能到底是哪些有帮助的反馈并进行相应的改进和更新。