拷贝与深拷贝

83 阅读1分钟

浅拷贝

  1. assign方法
let a = {age:1}

let b = Object.assign({}, a)
a.age = 2;
console.log(b.age); //1
  1. ...
let a = {age:1}
let b = {...a}
a.age = 2
console.log(b.age); //1

深拷贝

JSON.parse

//那么深拷贝如何去做呢
let c = JSON.parse(JSON.stringify(a))
a.jobs.first = 'native'
console.log(c.jobs.first);
// 有一些问题; undefined,循环引用
  • 他无法实现对函数 、RegExp等特殊对象的克隆
  • 会抛弃对象的constructor,所有的构造函数会指向Object
  • 对象有循环引用,会报错

简单手写 版本1 不满意,逻辑有些混乱

function deepClone(obj) {
    // 如果是 值类型 或 null,则直接return
    if(typeof obj !== 'object' || obj === null) {
        return obj
    }
    
    // 定义结果对象
    let copy = {}
    
    // 如果对象是数组,则定义结果数组
    if(obj.constructor === Array) {
        copy = []
    }
    
    // 遍历对象的key
    for(let key in obj) {
        // 如果key是对象的自有属性
        if(obj.hasOwnProperty(key)) {
            // 递归调用深拷贝方法
            copy[key] = deepClone(obj[key])
        }
    }
    
    return copy
} 

版本2

function deepClone(obj = {}){
  // 不是对象和数组 直接返回
  if(typeof obj !== 'object' || obj == null) {
    return obj
  }

  // 初始化返回结果  数组返回数组,对象返回对象
  let result
  if(obj instanceof Array) {
    result = []
  }else {
    result = {}
  }

  // 遍历
  for(let key in obj) {
    if(obj.hasOwnProperty(key)){
      // 保证key不是原型的属性
      result[key] = deepClone(obj[key])
    }
  }

  return result
}