实现深拷贝的方法

1.递归

// 递归调用
const deepCopy = (obj) => {
  // 判断传入的值是否为一个对象
  if (obj === null && typeof obj !== "object") {
    return obj;
  }
  // 判断对象的类型 注意这里不考虑包装类对象
  if (Object.prototype.toString.call(obj) === "[object Date]") {
    return new Date(obj);
  }
  if (Object.prototype.toString.call(obj) === "[object RegExp]") {
    return new RegExp(obj);
  }
  if (Object.prototype.toString.call(obj) === "[object Undefined]") {
    return new Error(obj);
  }
  // 判断对象是类
  let newObj = Array.isArray(obj) ? [] : {}
  for(let item in obj){
    if(typeof obj[item] === 'object') {
      newObj[item] = deepCopy(obj[item])
    }else {
      newObj[item] = obj[item]
    }
  }
  return newObj
}

2.

// JSON.stringify
// 情况一: 对象内不存在undefined、symbol、function类型的属性时
// const foo = {
//    name: '张三',
//    info: {
//      age: 24
//    }
// }
// const newFoo = JSON.parse(JSON.stringify(foo))
// console.log(foo, newFoo) // { name: '张三', info: { age: 24 } } { name: '张三', info: { age: 24 } }
// foo.info.age = 25
// console.log(foo, newFoo) // { name: '张三', info: { age: 25 } } { name: '张三', info: { age: 24 } }

// 情况二:当对象内存在undefined、symbol、function类型的属性时,在序列化过程中会被忽略。
// 当属性为NaN 和 Infinity 格式的数值及 null 都会被当做 nul
// const foo = {
//    name: "张三",
//    age: undefined,
//    height: 183,
//    gender: Symbol("男"), //
//    say: () => {},
//    aa: NaN,
// };
// const newFoo = JSON.parse(JSON.stringify(foo));
// console.log(foo, newFoo); // {aa: NaN, age: undefined, gender: Symbol(男), height: 183, name: "张三"} { {name: '张三', height: 183, aa: null} }

// JSON.stringify() 第二个参数为可选参数,可以是一个函数或者数组,
// 当是数组时表示需要被转化的属性列表,但undeinfed,symbol,function类型的属性依然会被忽略

// const newFoo = JSON.parse(JSON.stringify(foo, ['name', 'age', 'gender', 'say', 'aa']));
// console.log(newFoo) // {name: '张三', aa: null}

3.structuredClone()//存在兼容问题

const foo = {
  name: '张三',
  info: {
    age: 24
  }
}
const newFoo = structuredClone(foo) //
foo.info.age = 25
console.log(foo, newFoo) // { name: '张三', info: { age: 25 } } { name: '张三', info: { age: 24 } }

4.Object.assign // 只有当对象中没有嵌套对象时,才可以实现深拷贝

const foo = {
  name: '张三',
  age: 24
}
const newFoo = Object.assign({}, foo)
foo.age = 25
console.log(foo, newFoo) // {name: '张三', age: 25} {name: '张三', age: 24}

// 对象中有内嵌的对象时
const foo = {
  name: '张三',
  info: {
    age: 24
  }
}
const newFoo = Object.assign({}, foo)
foo.info.age = 25

foo.name= '李四'
console.log(foo, newFoo) // { name: '李四', info: { age: 25 } } { name: '张三', info: { age: 25 } }

posted @ 2023-04-11 17:28  活在当下_yzx  阅读(24)  评论(0)    收藏  举报