从结构上看,所有的数据(data)最终都可以分解成三种类型:
第一种类型是标量(scalar),也就是一个单独的字符串(string)或数字(numbers),比如"北京"这个单独的词。 第二种类型是序列(sequence),也就是若干个相关的数据按照一定顺序并列在一起,又叫做数组(array)或列表(List),比如"北京,上海"。 第三种类型是映射(mapping),也就是一个名/值对(Name/value),即数据有一个名称,还有一个与之相对应的值,这又称作散列(hash)或字典(dictionary),比如"首都:北京"。
Json格式:
1) 并列的数据之间用逗号(", ")分隔。
2) 映射用冒号(": ")表示。
3) 并列数据的集合(数组)用方括号("[]")表示。
4) 映射的集合(对象)用大括号("{}")表示。
比如,下面这句话:
"北京市的面积为16800平方公里,常住人口1600万人。上海市的面积为6400平方公里,常住人口1800万。"
写成json格式就是这样:
[
{"城市":"北京","面积":16800,"人口":1600},
{"城市":"上海","面积":6400,"人口":1800}
]
如果事先知道数据的结构,上面的写法还可以进一步简化:
[ ["北京",16800,1600], ["上海",6400,1800] ]
一、JSON构建
在JSON中,有两种结构:对象和数组。
1. “名称/值”对的集合
不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。
一个对象以“{”开始,“}”结束。每个“key”后跟一“:”,“‘key/value’ 对”之间运用 “,”分隔。
packJson = {"name":"nikita", "password":"1111"}
2. 值的有序列表
在大部分语言中,它被理解为数组(array)。
packJson = [{"name":"nikita", "password":"1111"}, {"name":"tony", "password":"2222"}];
数组是值的有序集合。一个数组以“[”开始,“]”结束。值之间运用 “,”分隔。
二、JSON对象和JSON字符串的转换
在数据传输流程中,json是以文本,即字符串的形式传递的,而JS操作的是JSON对象,所以,JSON对象和JSON字符串之间的相互转换是关键。例如:
JSON字符串:
var jsonStr = \'{"name":"nikita", "password":"1111"}\';
JSON对象:
var jsonObj = {"name":"nikita", "password":"1111"};
1、JSON对象转换为JSON字符串
function json2str(o){ var arr = []; var fmt = function(s) { if (typeof s == \'object\' && s != null) { return json2str(s); //递归 } //如果是数字或string return /^(string|number)$/.test(typeof s) ? "\'" + s + "\'" : s; } if(o.constructor === Array ){//数组 for ( var i in o) { arr.push(fmt(o[i])); } return \'[\' + arr.join(\',\') + \']\'; } else{//普通JSON对象 for ( var i in o) { arr.push("\'" + i + "\':" + fmt(o[i])); } return \'{\' + arr.join(\',\') + \'}\'; } }
var last = jsonObj.toJSONString(); //将JSON对象转化为JSON字符
2、JSON字符串转换为Json对象
var myObject = eval(\'(\'+jsonStr+\')\');
eval是js自带的函数,不是很安全,可以考虑用json包。
var myObject = jsonStr.parseJSON(); //由JSON字符串转换为JSON对象
Jquery方法:
$.parseJSON( jsonstr ); //jQuery.parseJSON(jsonstr),可以将json字符串转换成json对象
Function函数方法:
var json=\'{"name":"CJ","age":18}\'; data =(new Function("","return "+json))(); 此时的data就是一个会解析成一个 json对象了
特别注意:如果myObject本来就是一个JSON对象,那么使用eval()函数转换后(哪怕是多次转换)还是JSON对象,但是使用parseJSON()函数处理后会有问题(抛出语法异常)。
三、将两个JSON对象组装到一个里面
//targetJson 目标JSON,packJson 被组装JSON function addGroupJson(targetJson, packJson){ if(targetJson && packJson){ for(var p in packJson){ targetJson[p] = packJson[p]; } } }
用法如下:
var json1 = {"name":"nikita"}; var json2 = {"password":"1111"}; addGroupJson(json1, json2); alert(json2str(json1));
四、JS实现json查询
前一部分是简单的实现如何使用JS写模板,第二个就是具体的实现了JSON查询的一个扩展。
1 /* 定义模板函数 */ 2 var template = function (queryArr) { 3 var count = 0; 4 for (var i = 0; i < queryArr.length; i++) { 5 var e = queryArr[i]; 6 if ($express) { 7 count++; 8 } 9 } 10 return count; 11 } 12 13 /*模板创建函数 */ 14 var createIntance = function (exp) { 15 var fun = template.toString().replace("$express", exp).toString(); 16 return eval("0," + fun); 17 } 18 19 var testTodo = function () { 20 var testArr = [ 21 { name: "张三", age: 20 }, 22 { name: "李四", age: 25 }, 23 { name: "王二麻子", age: 28 }, 24 { name: "小张", age: 30 } 25 ]; 26 var func = createIntance("e.age>=25"); 27 alert(func(testArr)); 28 } 29 30 /****************** JS 实现 JSON查询 **********************/ 31 // 定义常用的函数 32 var len = function (s) { return s.length; } 33 var left = function (s, n) { return s.substr(0, n); } 34 var right = function (s, n) { return s.substr(-n); } 35 var index = function (s, find) { return s.indexOf(find) + 1; } 36 37 // 扩展原型方法 38 var _proto = Object.prototype; 39 // 缓存,解决快速查找 40 var _cache = {}; 41 // 扩展运算符 42 var _alias = [ 43 /@/g, "_e.", 44 /AND/gi, "&&", 45 /OR/gi, "||", 46 /<>/g, "!=", 47 /NOT/gi, "!", 48 /([^=<>])=([^=]|$)/g, \'$1==$2\' 49 ]; 50 51 var _rQuote = /""/g; 52 var _rQuoteTemp = /!~/g; 53 54 // 编译 55 var _complite = function (code) { 56 return eval("0," + code); 57 } 58 59 // 将扩展符号转换成标准的JS符号 60 var _interpret = function (exp) { 61 exp = exp.replace(_rQuote,"!~"); 62 var arr = exp.split(\'"\'); 63 var i, n = arr.length; 64 var k = _alias.length; 65 66 for (var i = 0; i < n; i += 2) { 67 var s = arr[i]; 68 for (var j = 0; j < k; j += 2) { 69 if (index(s, _alias[j]) > -1) { 70 s = s.replace(_alias[j], _alias[j + 1]); 71 } 72 } 73 arr[i] = s; 74 } 75 76 for (var i = 1; i < n; i += 2) { 77 arr[i] = arr[i].replace(_rQuoteTemp, \'\\"\'); 78 } 79 return arr.join(\'"\'); 80 } 81 82 // 定义模函数 83 var _templ = function (_list) { 84 var _ret = []; 85 var _i = -1; 86 87 for (var _k in _list) { 88 var _e = _list[_k]; 89 if (_e != _proto[_k]) { 90 if ($C) { 91 _ret[++_i] = _e; 92 } 93 } 94 } 95 return _ret; 96 } .toString(); 97 98 // 扩展查询的方法 99 _proto.Query = function (exp) { 100 if (!exp) { 101 return []; 102 } 103 var fn = _cache[exp]; 104 try { 105 if (!fn) { 106 var code = _interpret(exp); 107 code = _templ.replace("$C", code); 108 fn = _cache[exp] = _complite(code); 109 } 110 return fn(this); 111 } catch (e) { 112 return []; 113 } 114 } 115 116 var doTest = function () { 117 var heros = [ 118 // 名============攻=====防=======力量====敏捷=====智力==== 119 {name: \'冰室女巫\', DP: 38, AP: 1.3, Str: 16, Dex: 16, Int: 21 }, 120 { name: \'沉默术士\', DP: 39, AP: 1.1, Str: 17, Dex: 16, Int: 21 }, 121 { name: \'娜迦海妖\', DP: 51, AP: 6.0, Str: 21, Dex: 21, Int: 18 }, 122 { name: \'赏金猎人\', DP: 39, AP: 4.0, Str: 17, Dex: 21, Int: 16 }, 123 { name: \'剧毒术士\', DP: 45, AP: 3.1, Str: 18, Dex: 22, Int: 15 }, 124 { name: \'光之守卫\', DP: 38, AP: 1.1, Str: 16, Dex: 15, Int: 22 }, 125 { name: \'炼金术士\', DP: 49, AP: 0.6, Str: 25, Dex: 11, Int: 25 } 126 //... 127 ]; 128 var match = heros.Query(\'@Str>20 AND @Dex>20\'); 129 ShowResult(match[0]); 130 // 查询:“士”结尾的 131 // 结果:沉默术士,剧毒术士,炼金术士 132 var match = heros.Query(\'right(@name,1)="士"\'); 133 ShowResult(match[0]); 134 } 135 function ShowResult(result) { 136 alert(result.name + " " + result.DP + " " + result.AP + " " + result.Str + " " + result.Dex + " " + result.Int); 137 }