本文已参与[新人创作礼]活动,一起开启掘金创作之路。
JSON对象:JSON对象在大括号{}中书写,对象可包含多个key/value(键/值)对,key必须是字符串,value可以是合法的JSON数据类型(字符串、数字、对象、数组、布尔值或null),key和value之间使用冒号:分割,每个key/value对使用逗号,分割。
JSON数组:JSON数组在中括号中书写,JSON中数组数据类型必须是合法的JSON数据类型(字符串、数字、对象、数组、布尔值或null),在js中数组值可以是以上的JSON数据类型,也可以是js的表达式,包括函数、日期以及undefined。
JSON.parse()
JSON通常用于与服务端交换数据,如果在接收服务器数据是一个符合JSON格式的字符串时,可以使用JSON.parse()方法将数据转换成js对象。
使用语法:
JSON.parse(text[, reviver])
复制代码
其中,text是必需的参数,为一个有效的JSON字符串,reviver是可选的参数,为一个转换结果的函数,将为对象的每个成员调用此函数。
必需的参数text
text是必需的,为一个有效的JSON字符串。
注意:数据必须是标准的JSON格式,否则会解析出错。
// 定义一个符合JSON格式的字符串。
let jsonText = '{"name":"姓名","address":"上海市"}';
// 解析JSON
let obj = JSON.parse(jsonText);
console.log(obj);
console.log(obj.name);
复制代码
可选的参数reviver
reviver为可选的,为一个转换结果的函数,将为对象的每个成员调用此函数。
将时间字符串通过reviver函数处理,是日期参数,就转换成Date对象。
// 定义一个符合JSON格式的字符串。
let jsonText = '{"name":"姓名","address":"上海市","initDate":"2022-2-22"}';
// 解析JSON
let obj = JSON.parse(jsonText,(key,value)=>{
if(key == "initDate"){
return new Date(value);
}else{
return value;
}
});
console.log(obj);
复制代码
Date对象
JSON不能存储Date对象,若要存储Date对象,则需要将其转换成字符串,使用Date对象时再将字符串转换成Date对象。
// 定义一个符合JSON格式的字符串。
let jsonText = '{"name":"姓名","address":"上海市","initDate":"2022-2-22"}';
// 解析JSON
let obj = JSON.parse(jsonText);
console.log(obj);
console.log(obj.initDate);
console.log(new Date(obj.initDate));
复制代码
解析函数
JSON中不允许包括函数,可以将函数转换成字符串存储,之后再将字符串转换成函数。
// 定义一个符合JSON格式的字符串。
let jsonText = '{"name":"姓名","address":"上海市","func":"function () { console.log(\\"JSON->function\\");}"}';
// 解析JSON
let obj = JSON.parse(jsonText);
console.log(obj);
console.log(eval("(" + obj.func + ")"));
复制代码
eval() 函数作用: eval()可以接受一个字符串str作为参数,并把这个参数作为脚本代码来 执行。
JSON.stringify()
JSON通常用于与服务端交换数据,在向服务器发送数据时一般是字符串,可以使用JSON.stringify()方法将js对象转换成字符串。
使用语法:
JSON.stringify(value[, replacer[, space]])
复制代码
其中,value是必需的参数,为要转换的js值(通常为对象或数组),replacer是可选的参数,用于转换结果的函数或数组,space是可选的参数,为文本添加缩进、空格和换行符。
必需参数value
// 定义一个对象
let jsonObj = {
"name": "姓名",
"address": "上海市"
};
// 传换成字符串
let obj = JSON.stringify(jsonObj);
console.log(obj);
复制代码
可选参数replacer
如果 replacer 为函数,则 JSON.stringify 将调用该函数,并传入每个成员的键和值。使用返回值而不是原始值。如果此函数返回 undefined,则排除成员。根对象的键是一个空字符串:""。
// 定义一个对象
let jsonObj = {
"name": "姓名",
"address": "上海市"
};
// 传换成字符串
let obj = JSON.stringify(jsonObj,(key,value)=>{
if(key == 'name'){
return value+"这是对象的属性值";
}else{
return value;
}
});
console.log(obj);
复制代码
如果此函数返回 undefined,则排除成员。
// 定义一个对象
let jsonObj = {
"name": "姓名",
"address": "上海市"
};
// 传换成字符串
let obj = JSON.stringify(jsonObj,(key,value)=>{
if(key == 'name'){
return undefined;
}else{
return value;
}
});
console.log(obj);
复制代码
可选参数space
如果 space 是一个数字,则返回值文本在每个级别缩进指定数目的空格,如果 space 大于 10,则文本缩进 10 个空格。space 也可以使用非数字,如:\t。
// 定义一个对象
let jsonObj = {
"name": "姓名",
"address": "上海市"
};
// 传换成字符串
let obj = JSON.stringify(jsonObj,(key,value)=>{
if(key == 'name'){
return undefined;
}else{
return value;
}
},8);
console.log(obj);
复制代码
// 定义一个对象
let jsonObj = {
"name": "姓名",
"address": "上海市"
};
// 传换成字符串
let obj = JSON.stringify(jsonObj,(key,value)=>{
if(key == 'name'){
return value+"这是对象的属性值";
}else{
return value;
}
},'\t');
console.log(obj);
复制代码
对象中的Date对象
JSON 不能存储Date对象,JSON.stringify()会将日期对象转换成字符串。
// 定义一个对象
let jsonObj = {
"name": "姓名",
"address": "上海市",
"initDate": new Date("2022-2-22")
};
// 传换成字符串
let obj = JSON.stringify(jsonObj,(key,value)=>{
if(key == 'name'){
return value+"这是对象的属性值";
}else{
return value;
}
},8);
console.log(obj);
复制代码
解析函数
JSON 不允许包含函数,JSON.stringify() 会删除 JavaScript 对象的函数,包括 key 和 value。
// 定义一个对象
let jsonObj = {
"name": "姓名",
"address": "上海市",
"initDate": new Date("2022-2-22"),
"func": function(){ console.log("函数")}
};
// 传换成字符串
let obj = JSON.stringify(jsonObj,(key,value)=>{
if(key == 'name'){
return value+"这是对象的属性值";
}else{
return value;
}
},8);
console.log(obj);
复制代码
JSON.parse(JSON.stringify())
JSON.parse(JSON.stringify())实现深拷贝。
浅拷贝:一个新的对象直接拷贝已存在的对象的对象属性的引用,只是将对象的数据引用下来,依旧指向同一个存放地址,拷贝后的数据修改后,会影响原对象的数据。
深拷贝:将对象中所有数据拷贝下来,拷贝后的数据修改后不会影响原数据。
若obj⾥⾯存在时间对象,JSON.parse(JSON.stringify(obj))之后,时间对象会变成字符串。
若obj中的对象是由构造函数⽣成的,则使⽤JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor。
若对象中存在循环引⽤的情况也⽆法正确实现深拷贝。
若obj⾥有RegExp、Error对象,则序列化的结果将只得到空对象。
若obj⾥有函数,undefined,则序列化的结果会把函数, undefined丢失。
若obj⾥有NaN、Infinity和-Infinity,则序列化的结果会变成null。
浅拷贝
// 定义一个对象
let jsonObj = {
"name": "姓名",
"address": "上海市",
"initDate": new Date("2022-2-22"),
"func": function(){ console.log("函数")}
};
// 浅拷贝
let obj = jsonObj;
// 修改拷贝的对象的属性值
obj.name = 'object';
// 打印原对象的值
console.log(jsonObj);
复制代码
拷贝后的对象:
原对象,原对象的值改变了。
深拷贝
// 定义一个对象
let jsonObj = {
"name": "姓名",
"address": "上海市",
"initDate": new Date("2022-2-22"),
"func": function(){ console.log("函数")}
};
// 浅拷贝
let obj = JSON.parse(JSON.stringify(jsonObj));
// 修改拷贝的对象的属性值
obj.name = 'object';
// 打印原对象的值
console.log(jsonObj);
复制代码
拷贝后的对象:
原对象,原对象的值没有改变。