JSON

定义

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于阅读和编写,同时也易于机器解析和生成。它基于ECMA262语言规范(1999-12第三版)中JavaScript编程语言的一个子集。 JSON采用与编程语言无关的文本格式,但是也使用了类C语言(包括C, C++, C#, Java, JavaScript, Perl, Python等)的习惯,这些特性使JSON成为理想的数据交换格式。

结构

  • “名称/值”对的集合不同语言中,它被理解为对象(object),记录(record),结构(struct),字典(dictionary),哈希表(hash table),键列表(keyed list)等

  • 值的有序列表多数语言中被理解为数组(array)JSON使用。JSON以一种特定的字符串形式来表示 JavaScript 对象。如果将具有这样一种形式的字符串赋给任意一个 JavaScript 变量,那么该变量会变成一个对象引用,而这个对象就是字符串所构建出来的,好像有点拗口,我们还是用实例来说明。 这里假设我们需要创建一个User对象,并具有以下属性 :用户ID 用户名。

JSON的值可以是数字(整数或浮点数)、字符串、布尔值、数组、对象、null,这些结构都可以嵌套。

您可以使用以下JSON形式来表示User对象:

1
let user = {"userId":100, "name":"Hulk-lv"};

我们也可以定义一个用户列表:

1
2
3
4
5
let userList = [
{"userId":11, "name":{"firstName":"Truly","lastName":"Zhu"}},
{"userId":12, "name":{"firstName":"Jeffrey","lastName":"Richter"}},
{"userId":13, "name":{"firstName":"Scott","lastName":"Gu"}
];

常用方法

JSON.parse()

  • 作用:将 JavaScript 对象表示法 (JSON) 字符串转换为对象。  

  • 语法:JSON.parse(text [, reviver])

  • 参数:
    text  必需。 一个有效的 JSON 字符串。
    reviver  可选。 一个转换结果的函数。 将为对象的每个成员调用此函数。
    返回值:一个对象或数组

1
2
let json = '{"name":"GDT","age":23,"University":"GDUT"}';
let info = JSON.parse(json);  //解析为JSON对象

JSON.stringify()

  • 作用:将 JavaScript 值转换为 JavaScript 对象表示法 (JSON) 字符串

  • 语法:JSON.stringify( value [, replacer] [, space])

  • 参数:
    value  必需,通常为需要转换的JavaScript值(通常为对象或者数组)
    replacer  可选,用于转换结果的函数或者数组
    space  可选。向返回值 JSON 文本添加缩进、空格和换行符以使其更易于读取。
    返回值:一个包含JSON文本的字符串

1
2
let info = {name:"GDT",age:23,University:"GDUT"};
let json = JSON.stringify(info); //转换为JSON字符串

eval()

  • 作用:eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。

  • 语法:eval(string)

  • 参数:
    string  必需,要计算的字符串,其中含有要计算的 JavaScript 表达式或要执行的语句。
    返回值:返回计算string的值,如果有的话 (没有则不做任何改变返回)

1
2
3
4
eval("x=10;y=20;console.log(x*y)"); //200
console.log(eval("2+2"));  //4
let x=10;
console.log(eval(x+17));  //27

使用eval()函数也可以将JSON字符串解析为对象,这个功能能完成JSON.parse()的功能,但是有不一样的地方,请看下面代码:

1
2
3
4
5
6
7
8
9
// JSON.parse()
let json = '{"name":"GDT","age":23,"University":"GDUT"}';
let info = JSON.parse(json);    //解析为JSON对象
console.log(info); //[object Object]
//eval()
let json = '{"name":"GDT","age":23,"University":"GDUT"}';
let info = eval('(' + json + ')'); //解析为JSON对象
console.log(info); //[object Object]

注:eval()还要用一对圆括号将字符串包起来。相对于写法格式严格的JSON.parse()来说,eval()可以解析任何字符串,eval是不安全的,因为eval比较宽松,会有潜在的安全性问题。
例如:

1
2
3
4
let str1 = '{"a":"b"}';
console.log(eval("("+str1+")")); //正常解析为对象
let str2 = '{"a": (function(){alert("I can do something bad!");})()}';
eval('('+str2+')'); //可以用来执行木马脚本

序列化与解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
var jsonObj = {name: 'lvxj',age: '18',home: 'haidian'};
var jsonText = JSON.stringify(jsonObj);
var jsonObj2 = JSON.parse(jsonText);
console.log(jsonObj == jsonObj2); //false
console.log(jsonObj === jsonObj2); //false
//序列化
var jsonObj = {name: 'lvxj',age: '18',friends: ["aaa","bbb"], home: 'haidian'};
var jsonText1 = JSON.stringify(jsonObj, ["name", "age"]);
console.log(jsonText1);//{"name":"lvxj","age":"18"}
var jsonText2 = JSON.stringify(jsonObj, function(key, value){
switch(key) {
case "friends": return value.join(",");
case "age": return undefined;
default: return value;
}
});
console.log(jsonText2);//{"name":"lvxj","friends":"aaa,bbb","home":"haidian"}
var jsonText3 = JSON.stringify(jsonObj, null, 4);//第三个参数如果是一个数字表示每个级别缩紧的空格数,如果是一个字符串,将被当作缩紧字符(不要使用空格)
console.log(jsonText3);
/*输出 
{
"name": "lvxj",
"age": "18",
"friends": [
"aaa",
"bbb"
],
"home": "haidian"
}
*/
var jsonText4 = JSON.stringify(jsonObj, null, "--");
console.log(jsonText4);
/*
{
--"name": "lvxj",
--"age": "18",
--"friends": [
----"aaa",
----"bbb"
--],
--"home": "haidian"
}
*/
var jsonObj = {name: 'lvxj',age: '18',friends: ["aaa","bbb"], home: 'haidian',
toJSON: function(){ return this.name; }
};
var jsonText5 = JSON.stringify(jsonObj);
console.log(jsonText5);//"lvxj"
//序列化顺序
var jsonObj = {name: 'lvxj',age: '18',friends: ["aaa","bbb"], home: 'haidian',
toJSON: function(){ return {name: 'lvxj',age: '18',friends: ["aaa","bbb"]}; }
};
var jsonText6 = JSON.stringify(jsonObj, function(key, value){
switch(key) {
case "friends": return value.join(",");
case "age": return undefined;
default: return value;
}
},"--");
console.log(jsonText6);
/*
{
--"name": "lvxj",
--"friends": "aaa,bbb"
}
*/
//解析选项
var jsonObj = {name: 'lvxj',age: '18',friends: ["aaa","bbb"], releaseDate: new Date(2011,1,1)};
console.log(jsonObj)
var jsonText7 = JSON.stringify(jsonObj);
console.log(jsonText7);//{"name":"lvxj","age":"18","friends":["aaa","bbb"],"releaseDate":"2011-01-31T16:00:00.000Z"}
var jsonObjCopy = JSON.parse(jsonText7, function(key, value){
if(key == 'releaseDate') {
return new Date(value);
} else { return value}
});
console.log(jsonObjCopy)//releaseDate的值会是一个Date对象