JSON.parse()、JSON.stringify()、JSON.parse(JSON.stringify())

本文已参与[新人创作礼]活动,一起开启掘金创作之路。

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);
复制代码

image.png

可选的参数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);
复制代码

image.png

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));
复制代码

image.png

解析函数

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 + ")"));
复制代码

image.png

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);
复制代码

image.png

可选参数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);
复制代码

image.png

如果此函数返回 undefined,则排除成员。

// 定义一个对象
let jsonObj = {
  "name": "姓名",
  "address": "上海市"
};
// 传换成字符串
let obj = JSON.stringify(jsonObj,(key,value)=>{
  if(key == 'name'){
    return undefined;
  }else{
    return value;
  }
});
console.log(obj);
复制代码

image.png

可选参数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);
复制代码

image.png

// 定义一个对象
let jsonObj = {
  "name": "姓名",
  "address": "上海市"
};
// 传换成字符串
let obj = JSON.stringify(jsonObj,(key,value)=>{
  if(key == 'name'){
    return value+"这是对象的属性值";
  }else{
    return value;
  }
},'\t');
console.log(obj);
复制代码

image.png

对象中的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);
复制代码

image.png

解析函数

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);
复制代码

image.png

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);
复制代码

拷贝后的对象:

image.png

原对象,原对象的值改变了。

image.png

深拷贝

// 定义一个对象
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);
复制代码

拷贝后的对象:

image.png

原对象,原对象的值没有改变。

image.png

来源:https://juejin.cn/post/7101691067619082247
posted @ 2022-08-31 23:27  程序员小明1024  阅读(111)  评论(0编辑  收藏  举报