1.实现浅拷贝

  1. // 1. ...实现
  2. let copy1 = {...{x:1,y:2}}
  3. // 2. Object.assign实现
  4. let copy2 = Object.assign({}, {x:1,y:2})
  5. // 如果copy2中对象的某个属性是复杂数据类型(array,object)Object.assign就无效
  6. copy2={
  7. x:1,
  8. y:[2,3,4]
  9. }

2. 实现深拷贝

// 1. JOSN.stringify()/JSON.parse()
let obj = {a: 1, b: {x: 3}}
JSON.parse(JSON.stringify(obj))

// 2. 递归拷贝
function deepClone(obj) {
  let copy = obj instanceof Array ? [] : {}
  for (let i in obj) {
    if (obj.hasOwnProperty(i)) {
      copy[i] = typeof obj[i] === 'object' ? deepClone(obj[i]) : obj[i]
    }
  }
  return copy
}

image.png

3. JSON.stringify深拷贝的缺点(总结有以下6点)

1、如果obj里面存在时间对象,JSON.parse(JSON.stringify(obj))之后,时间对象变成了字符串。
2、如果obj里有RegExp、Error对象,则序列化的结果将只得到空对象。
3、如果obj里有函数,undefined,则序列化的结果会把函数, undefined丢失。
4、如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null。
5、JSON.stringify()只能序列化对象的可枚举的自有属性。如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor。
6、如果对象中存在循环引用的情况也无法正确实现深拷贝。

1.如果 obj 里面有时间对象,则 JSON.stringify 后再 JSON.parse 的结果,时间将转为字符串的形式,而不是对象的形式

let obj = {
    a:123,
    b:[new Date(),new Date()]
}
let newObj = JSON.parse(JSON.stringify(obj));
console.log(obj,newObj);

image.png

2.如果 obj 里有 RegExp (正则表达式的缩写)、Error 对象,则序列化的结果将只得到空对象

let obj = {
    a: 123,
    b: /aabb[a-z]\d/,
    c: new TypeError('typeError')
}
let newObj = JSON.parse(JSON.stringify(obj));
console.log(obj,newObj);

image.png

3. 如果 obj 里有函数(function),undefined,Symbol 则序列化的结果会把 function 或 undefined 丢失

let obj = {
    a:123,
    fn:function(){let a = 123;console.log(a)},
    c:undefined,
    d:Symbol('foo')
}
let newObj = JSON.parse(JSON.stringify(obj));
console.log(newObj)

image.png

4. 如果obj里有 NaN、Infinity 和 -Infinity,则序列化的结果会变成 null

let obj = {
    a:123,
    b:NaN,
    c:Infinity,
    d:-Infinity
}
let newObj = JSON.parse(JSON.stringify(obj));

image.png

5. JSON.stringify() 只能序列化对象的可枚举的自有属性,例如如果 obj 中的对象是有构造函数生成的, 则使用 JSON.parse(JSON.stringify(obj)) 深拷贝后,会丢弃对象的 constructor

class Student{
    constructor(){
        this.a = 1;
        this.b = 2;
    }
}
let obj = {
    a:123,
    b:new Student()
}
let newObj = JSON.parse(JSON.stringify(obj));

image.png