JavaScript浅拷贝与深拷贝以及对象与JSON格式的转换JSON.stringify、JSON.parse

   浅拷贝 : 对于引用类型而言,指两个引用类型指向同一个地址,改变一个,另一个也会随之改变。


   例如当设置 ku 的变量值 为 {age : 18} , angel 的变量值指向 ku, 在栈内存里,angel 的内存地址和 ku 是一样的,在堆内存里,它们是同一个 object 对象。



在这里插入图片描述



   当改变 ku age 的属性值时,angel age的属性值也随之改变。



在这里插入图片描述



   深拷贝: 对于引用类型而言,复制后引用类型指向一个新的内存地址,两个对象改变互不影响。


   首先简单介绍 JSON(JavaScript Object Notation)是JavaScript表达值和对象的通用数据格式,其本质就是符合一定规范的字符串。由于JSON的优良特性,非常容易和其他语言进行数据交换,尤其在前后端交互方面。


   在之前的博客也分享了一个关于 JS 反序列化的爬虫项目案例,这里先通过以下序列化和反序列化的例子,说明深拷贝与浅拷贝的区别,接着会详细举例说明序列化和反序列化的各种用法。


   通过 JSON.stringify (序列化) 转化为 JSON 字符串格式



在这里插入图片描述



   再通过 JSON.parse (反序列化) ,赋值给 angel, 当 ku age 的改变时, angel age 的值不变。 也就是 在栈内存和堆内存里,ku 和 angel 各自有独立的 内存地址和 object 对象,当发生改变时,两者互不影响。



在这里插入图片描述



   == 注意:基础类型的赋值和深拷贝相似,但不属于深拷贝 。==



在这里插入图片描述



   使用JSON.stringify(obj)方法会返回该对象obj的JSON字符串数据,但归属于JavaScript语言本身的非数据属性会被JSON.stringify跳过,这包括对象方法、Symbol类型、undefined的属性。



   可见,输出为空的内容

在这里插入图片描述



   并非所有的对象都能转为JSON格式,如果对象之间存在循环引用,就会导致转换失败。失败的原因是由于 teacher 引用了 student, student 反过来又引用了 teacher。



在这里插入图片描述



   如果想只将对象的个别属性转为JSON格式,或者摆出循环应用中的属性,可以 通过 let json = JSON.stringify(obj[,replacer,space]),其中参数 obj : 要编码的对象;replacer:要编码的属性数组或者映射函数function(k,v);space:用于格式化的空格数量。



  
在这里插入图片描述



   如果想要在第二个参数传入一个数组,那么JSON.stringify就会只把数组中的名称转为JSON格式,这样计算对象存在循环引用,同样能够成功的转格式。


   如果我们希望序列化出循环应用外的所有对象属性,只需要把对象的所有属性名写入数组即可,这对对象的子对象同样生效。


   执行结果如下,但还存在一个问题,如果对象属性特别多,可能数组就会非常长,代码也会很冗长,这种情况下就需要使用映射函数。



在这里插入图片描述



   映射函数: 我们可以创建一个函数,代替数组作为replacer,这个函数接收(key,value)作为参数,并决定如何序列化对应的属性。


   例如,在解决循环引用的时候,我们排除引用属性。由于值为undefined的属性会被JSON.stringify忽略,这样我们就可以轻松的排除所有不希望出现的属性了。

在这里插入图片描述



   格式化使用的空格数量: JSON.stringify(value, replacer, spaces)的第三个参数spaces可以指定JSON字符串的缩进空格数,常用的数值有2、4两种。在以上例子中,没有指定缩进空格数量,所以格式化后的JSON字符串都是没有格式的。


   这样输出的缩进更加清晰



在这里插入图片描述



   自定义toJSON方法: 和toString一样,对象的toJSON方法会在序列化的时候调用,我们可以通过重写这个方法改变序列化的方式。


   可以看到,在重写了对象的toJSON方法后,使用stringify的结果发生了改变。我们可以根据自己的需要重写toJSON方法,从而达到要的结果。



在这里插入图片描述



   JSON.parse: 之前简单介绍了反序列化的例子,现在就详细介绍如何把JSON字符串转为对象。语法:let obj = JSON.parse(str,[reviver]) 。 str 要解析的 JSON 字符串; reviver 可选的函数 function(key,value),该函数将为每个 (key, value) 对调用,并可以对值进行转换。



在这里插入图片描述



   使用reviver, 例如当我们要将字符串’{“title”:“Conference”,“date”:“2017-11-30T12:00:00.000Z”}’ 转为对象,结果会遇到报错。原因是date属性被转为了字符串,而不是Date对象。



在这里插入图片描述



   这就需要使用reviver函数将date转为Date对象:



在这里插入图片描述



   receiver 也可用于嵌套对象



在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值