一、赋值

  • 把一个对象a赋值给一个对象b,相当于把一个对象b的地址指向对象a的地址,他们指向同一片内存,b不过是a的别名,是引用;所以,他们实际上是同一个对象。

以下图直接赋值的例子,a对象中有两个属性,一个是name,一个是对象属性action;为什么要弄一个对象属性,这个会涉及到后面的浅拷贝和深拷贝问题,这也是他们之间的区别。

我们可以通过严格相等运算符"==="来检测二者是否指向同一个地址。

java 一个对象给另一个对象赋值 对象赋值给另一个对象js_JSON

  • 以刚才的例子为例,如下图所示。给b的name属性赋值'李四',给b的对象属性action的sing属性赋值'后来',a也发生了改变。

即:直接赋值,修改赋值后的对象b的非对象属性,也影响原对象a的非对象属性;修改赋值后的对象b的对象属性,也影响原对象a的对象属性

 

java 一个对象给另一个对象赋值 对象赋值给另一个对象js_浅拷贝_02

二、浅拷贝

  • 浅拷贝只会赋值对象的非对象属性,不会指向同一个地址。ES6中有个浅拷贝的方法Object.assign(target, ...sources)。以之前直接赋值的对象为例,如下图所示。

java 一个对象给另一个对象赋值 对象赋值给另一个对象js_java 一个对象给另一个对象赋值_03

  •  修改赋值后的对象b的非对象属性,不会影响原对象a的非对象属性;修改赋值后的对象b的对象属性,却影响原对象a的对象属性,如下图所示。

java 一个对象给另一个对象赋值 对象赋值给另一个对象js_浅拷贝_04

  •  es6中还有一个扩展运算符"..."也可以实现浅拷贝,还是以之前的对象为例,可以写成这种形式:var b= { ...a};如下图所示。

java 一个对象给另一个对象赋值 对象赋值给另一个对象js_赋值_05

  • 也可以用 for(let key in object){} 赋值来实现浅拷贝,如下图所示

java 一个对象给另一个对象赋值 对象赋值给另一个对象js_赋值_06

三、深拷贝

  • 深拷贝会另外拷贝一份一个一模一样的对象,但是不同的是会从堆内存中开辟一个新的区域存放新对象,新对象跟原对象不再共享内存,修改赋值后的对象b不会改到原对象a。

深拷贝,修改赋值后的对象b的非对象属性,不会影响原对象a的非对象属性;修改赋值后的对象b的对象属性,也不会影响原对象a的对象属性。而且,二者不指向同一个对象。

比较笨一点的办法就是将自己需要的数据自己封装起来。

 

let object={
                           repayment:this.ruleForm.repayment,
                           interestType:this.ruleForm.interestType,
                           productDeadline:this.ruleForm.productDeadline,
                           circumstancesOfDetention:this.ruleForm.circumstancesOfDetention,
                           }
                      this.tableData.push(object);
  • 但是,这样明显会使代码很臃肿,而且,这还是在需要的数据只有4条的情况下,如果这个object需要封装十几条非对象属性的情况下,明显结构不复杂的情况下,这种代码需要改进。

  有一种非常简单的方法就是序列化成为一个JSON字符串,将对象的内容转换成字符串的形式,再用JSON.parse()反序列化将JSON字符串变成一个新的对象,这样原对象就与复制后的新对象没了必然的关系。写法如下:

var b=JSON.parse(JSON.stringify(a));如下图所示

java 一个对象给另一个对象赋值 对象赋值给另一个对象js_赋值_07

 

  • 但是由于用到了JSON.stringify(),这也会导致一系列的问题,因为要严格遵守JSON序列化规则:原对象中如果含有Date对象,JSON.stringify()会将其变为字符串,之后并不会将其还原为日期对象。或是含有RegExp对象,JSON.stringify()会将其变为空对象,属性中含有NaNInfinity-Infinity,则序列化的结果会变成null,如果属性中有函数,undefined,symbol则经过JSON.stringify()序列化后的JSON字符串中这个键值对会消失,因为不支持。