最近使用JSON很频繁,索性就好好整理一番,其实思路就是《Javascript高级程序设计》里面的提炼。
概念解释
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 这些特性使JSON成为理想的数据交换语言。 —————百度
JSON 全称为 JavaScript Object Notation(JavaScript对象表示法),它利用与 JavaScript 对象相似的表示方法来表示数据。虽然 JSON 脱胎于 JavaScript,但是 JSON 并不属于 JavaScript 的一部分,很多的语言都可以解析和序列化 JSON。
数据特点
- JSON 指的是 JavaScript 对象表示法(JavaScript Object Notation)
- 是轻量级的文本数据交换格式
- JSON 语法是 JavaScript 对象表示法语法的子集,但独立于任何语言之外
- 具有自我描述性,更易理解
- 可通过 JavaScript 进行解析
- 纯文本,数据可使用 AJAX 进行传输
JSON语法规则
数据结构
JSON 语法是 JavaScript 对象表示法语法的子集。
-
数据在名称/值对中,数据由逗号分隔,花括号保存对象,方括号保存数组,对象的属性必须要用双引号引起来,单引号会出错,同时JSON里没有变量的概念,也没有length属性。
-
需要注意的是,也是与 JavaScript对象表示方法的不同之处,JSON 字符串当中对象的属性必须加上双引号。(再强调一遍)
-
JSON简单值一般很少用,就在在大括号里填充数据。简单值包括字符串、数值、布尔值和 null。
-
JSON对象是名/值对的集合,类似于Python中的字典,对象,与 JavaScript对象相似,表示无序的键值对。键值对中的值可以是简单值,也可以是对象或数组。
-
JSON数组是值的有序列表,类似于Javascript中的数组。表示一组有序的值,数组的值可以是简单值,也可以是对象或数组。
表示记号
- 花括号(’{‘,’}’):表明一个对象,
- 中括号(’[’,’]’):表明一个数组,
- 逗号(’,’):表示并列关系,
- 任何空白符(空格、回车符、制表符等):为了视觉上的好看。
值的类型
- 字符串:C语言的风格,可包含转义字符,使用Unicode字符,
- 数值:C语言风格,可采用e/E来科学记数,小数等,
- true:“真”,false:“假”,
- null:表示无内容,
- 对象:上面说的名/值对的集合,
- 数组:值的有序列表。
注意
除以上6种外,再无其他,没有像js一样的undefined、NAN
1) 并列的数据之间用逗号(", ")分隔。
2) 映射用冒号(": ")表示。
3) 并列数据的集合(数组)用方括号("[]")表示。
4) 映射的集合(对象)用大括号("{}")表示。
举例
一个例子(JSON对象):
{
"name": "kaychen",
"age": 23,
"address": {
"province": "HuBei",
"city": "WuHan"
},
"gender": true,
"contact": [
"office": "1234-7654321",
"private": "15671592309"
],
"friends": ["bc", "cc", "dc"],
"blog": "http://littlewhitechen.github.io/"
}
一个例子(JSON数组):
[
"Tom": {
"title": "professor",
"department": "logistic",
"salary": 6516.52
},
"Jerry": {
"title": "teacher",
"department": "logistic",
"salary": 4358.64
}
]
从上可以看出,JSON可以无限嵌套。
JSON语法解析
原始的eval()解析
在 JSON 诞生之初 JavaScript 处理 JSON 的方式基本就靠 eval() 函数。 eval() 函数使用的是 JavaScript 编译器,可解析 JSON 文本,然后生成 JavaScript 对象。必须把文本包围在括号中,这样才能避免语法错误:var obj = eval (“(“ + txt + “)”);
<body>
<p>
First Name: <span id="fname"></span>
<br /> Last Name: <span id="lname"></span>
<br />
</p>
<script type="text/javascript">
var txt = '{"employees":[' + //注意javascript的字符串连接的规则
'{"firstName":"Bill","lastName":"Gates" },' +
'{"firstName":"George","lastName":"Bush" },' +
'{"firstName":"Thomas","lastName":"Carter" }]}';
var obj = eval("(" + txt + ")");
document.getElementById("fname").innerHTML = obj.employees[1].firstName
document.getElementById("lname").innerHTML = obj.employees[1].lastName
</script>
</body>
原生序列化和解析
在浏览器中,这提供了原生的 JSON 支持,而且 JSON 解析器的速度更快。 eval() 函数可以解析 JSON 然后返回 JavaScript 数组。但是由于 eval() 存在安全的风险,因此在 EMCAScript 5 开始有了一个新的全局对象 JSON对象用来处理 JSON。
较新的浏览器和最新的 ECMAScript (JavaScript) 标准中均包含了原生的对 JSON 的支持。
stringify()
JavaScript使用JSON对象的stringify()方法来序列化Javascript,将其转换成JSON。
var person = {
"name": "kaychen",
"age": 23,
"address": {
"province": "HuBei",
"city": "WuHan"
},
"gender": true,
"contact": [
"office": "1234-7654321",
"private": "15671592309"
],
"friends": ["bc", "cc", "dc"],
"blog": "http://littlewhitechen.github.io/"
}
var jsonText = JSON.stringify(person);
// 结果自己可以尝试一下
JSON.stringify() 方法在默认情况下输出的 JSON字符串不包含空格字符和缩进。
如果 JavaScript对象当中包含不被 JSON 支持的类型(如:undefined,函数,正则表达式)会自动被 stringigy() 方法忽略。只会输出可以识别的数据。
var person = {
name: "kaychen",
blog: undefined,
todo: function() {
return "sleep";
}
};
var jsonText = JSON.stringify(person);
console.log(jsonText);
// {"name":"kaychen"}
JSON.stringify() 方法包含三个参数,第一个参数就是要序列化的 JavaScript对象。第二个参数完成过滤输出结果功能。第三个参数控制输出字符串的缩进。
1、过滤输出结果
第二个参数完成过滤输出结果功能。
当传入的第二个参数为数组时,输出的 JSON字符串只会保留包含在该数组里面的属性值。
var person = {
name: "kaychen",
age: 23,
address: {
province: "Hubei",
city: "WuHan"
},
friends: ["bc", "cc", "dc"],
blog: "http://littlewhitechen.github.io/"
};
var jsonText = JSON.stringify(person, ["name","blog"]);
console.log(jsonText);
// {"name":"kaychen","blog":"http://littlewhitechen.github.io/"}
当传入的第二个参数为函数,该函数包含两个参数,分别是 JavaScript对象的属性名和属性值。输出的 JSON字符串会受到该函数的返回值影响。
// 省略 person对象
var jsonText = JSON.stringify(person, function(key, value) {
if (key === "name") {
return "ac";
} else if (key === "age") {
value++;
return value;
} else {
return value;
}
});
console.log(jsonText);
// {"name":"ac","age":24,"address":{"province":"HuBei","city":"WuHan"},"friends":["bc","cc","dc"],"blog":"http://littlewhitechen.github.io/"}
2、控制缩进
第三个参数控制输出字符串的缩进。
当第三个参数传入一个数值的时候,表示输出字符串缩进的空格数。
// 省略 person对象
var jsonText = JSON.stringify(person, null, 2);
console.log(jsonText);
// 输出
{
"name": "kaychen",
"age": 23,
"address": {
"province": "HuBei",
"city": "WuHan"
},
"friends": [
"bc",
"cc",
"dc"
],
"blog": "http://littlewhitechen.github.io/"
}
当第三个参数传入一个字符串时,输出结果会以该字符串作为缩进符号。
// 省略 person对象
// 使用 * 号缩进
var jsonText = JSON.stringify(person, null, "*");
使用制表符(Tab)缩进
// 省略 person对象
// 使用制表符(Tab)缩进
var jsonText = JSON.stringify(person, null, "\t");
3、自定义序列化
如果上述的方法都不能满足要求,还可以在要序列化的 JavaScript对象当中加入 toJSON() 函数,可以返回任何想返回的值。
var person = {
"name": "kaychen",
"age" 23,
"address": {
province: "Hubei",
city: "WuHan"
},
"friends": ["bc", "cc", "dc"],
"blog": "http://littlewhitechen.github.io/",
toJSON: function() {
this.name = "ac";
return "yoyo " + this.name;
}
};
var jsonText = JSON.stringify(person);
console.log(jsonText);
// "yoyo ac"
parse()
解析JSON格式数据,JavaScript 使用 JSON对象的 parse() 方法来解析 JSON。经常用来解析从后台服务器获取的JSON格式的数据,然后在前端来调用。
var jsonText = '{"name":"kaychen","age":23,"address":{"province":"Hubei","city":"WuHan"},"friends":["bc","cc","dc"],"blog":"http://littlewhitechen.github.io/"}';
var person = JSON.parse(jsonText);
console.log(person);
{
"name": "kaychen",
"age": 23,
"address": {
"province": "HuBei",
"city": "WuHan"
},
"friends": [
"bc",
"cc",
"dc"
],
"blog": "http://littlewhitechen.github.io/"
}
JSON.parse(jsonText,function(kay,value){}) 同样可以传入一个函数作为参数,对键值对进行操作。这个函数叫做还原函数,同时这个函数还是接受两个参数,一个键,一个值。而且需要返回一个值。
php中对json的支持
json_encode json_decode json_last_error json_decode的例子:
<?php
$arr = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5);
echo json_encode($arr);
?>
结果为:
{"a":1,"b":2,"c":3,"d":4,"e":5}
json_decode的原型为
mixed json_decode ($json [,$assoc = false [, $depth = 512 [, $options = 0 ]]])
如果assoc为true,解析json字符串会得到关联数组,相当于python中的字典。 否则会得到对象。
<?php
$json = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
var_dump(json_decode($json));
var_dump(json_decode($json, true));
?> 会得到:
object(stdClass)#1 (5) {
["a"] => int(1)
["b"] => int(2)
["c"] => int(3)
["d"] => int(4)
["e"] => int(5)
}
array(5) {
["a"] => int(1)
["b"] => int(2)
["c"] => int(3)
["d"] => int(4)
["e"] => int(5)
}
补充:
从结构上看,所有的数据(data)最终都可以分解成三种类型:
-
第一种类型是标量(scalar),也就是一个单独的字符串(string)或数字(numbers),比如”北京”这个单独的词。
-
第二种类型是序列(sequence),也就是若干个相关的数据按照一定顺序并列在一起,又叫做数组(array)或列表(List),比如”北京,上海”。
-
第三种类型是映射(mapping),也就是一个名/值对(Name/value),即数据有一个名称,还有一个与之相对应的值,这又称作散列(hash)或字典(dictionary),比如”首都:北京”。
在编程语言中,只要有了数组(array)和对象(object)就能够储存一切数据了。
数组和对象的另一个区别是,数组的数据没有”名称”(name),对象的数据有”名称”(name)。
JavaScript中有5种简单数据类型(也称为基本数据类型):Undefined、Null、Boolean、Number和String。还有1种复杂数据类型——Object,Object本质上是由一组无序的名值对组成的。
对一个值使用typeof操作符可能返回下列某个字符串:
-
“undefined”——如果这个值未定义;
-
“boolean”——如果这个值是布尔值;
-
“string”——如果这个值是字符串;
-
“number”——如果这个值是数值;
-
“object”——如果这个值是对象或null;
-
“function”——如果这个值是函数;
Undefined类型:
`Undefined`类型只有一个值,在使用var声明变量但未对其加以初始化时,
这个变量的值就是undefined
Null类型
Null类型是第二个只有一个值的数据类型,这个特殊的值是null。从逻辑角度来看,null值表示一个空对象指针,而这也正是使用typeof操作符检测null时会返回”object”的原因,例如:
var car = null;
alert(typeof car); // "object"
Number类型
这种类型用来表示整数和浮点数值,还有一种特殊的数值,即NaN(非数值 Not a Number)。这个数值用于表示一个本来要返回数值的操作数未返回数值的情况(这样就不会抛出错误了)。
String类型
String类型用于表示由零或多个16位Unicode字符组成的字符序列,即字符串。字符串可以由单引号(‘)或双引号(“)表示。
数值、布尔值、对象和字符串值都有toString()方法。但null和undefined值没有这个方法。
多数情况下,调用toString()方法不必传递参数。但是,在调用数值的toString()方法时,可以传递一个参数:输出数值的基数。
var num = 10;
alert(num.toString()); //"10"
alert(num.toString(2)); //"1010"
alert(num.toString(8)); //"12"
alert(num.toString(10)); //"10"
alert(num.toString(16)); //"a"
在不知道要转换的值是不是null或undefined的情况下,还可以使用转型函数String(),这个函数能够将任何类型的值转换为字符串。String()函数遵循下列转换规则:
● 如果值有toString()方法,则调用该方法(没有参数)并返回相应的结果
● 如果值是null,则返回”null”
● 如果值是undefined,则返回”undefined”
Object类型
对象其实就是一组数据和功能的集合。对象可以通过执行new操作符后跟要创建的对象类型的名称来创建。而创建Object类型的实例并为其添加属性和(或)方法,就可以创建自定义对象。
var o = new Object();
typeof 操作符
var s = "Nicholas";
var b =true;
var c = 21;
var u;
var n = null;
var o = {};
var obj = new Object;//最好写出new object()形式
alert(typeof s);//string
alert(typeof b);//boolean
alert(typeof c);//number
alert(typeof u);//undefined
alert(typeof n);//object
alert(typeof o);//object
alert(typeof obj);//object
typeof只能检测基本数据类型(除了null),引用数据类型还是的依靠instanceof来检测或者数组的专用Array.isArray()方法