js深浅拷贝

73 阅读1分钟

用处

当我们需要对一个引用值进行复制时,我们就需要用到拷贝

例子

原始值拷贝

    let a = 12
    let b = a
    a = 13
    console.log(b) // 打印出 12

引用值拷贝(错误版)

如果我们使用与原始值相同的拷贝方法就会出现以下结果

     let obj1 = {
        name: "小明",
        age: 17
     }
     let obj2 = obj1
     obj1.name = "小红"
     console.log(obj2.name) // 此时输出为小明

因为对 obj2 进行赋值时,仅仅复制了 obj1 的指针,而指针的指向仍然是同一个对象,所以当我们通过 obj1 改变的对象与 obj2 指向的对象是同一个对象;

浅拷贝

  • es3写法
 let obj1 = {
     name: "小明",
     age: 17
 }   
 function simpleClone(obj) {
   var cloneObj = {}
   // es3 的写法
   for(let i in obj) {
     cloneObj[i] = obj[i]
   }
   return cloneObj
 }
 let obj2 = simpleClone(obj1)
 obj1.name = "小红"
 console.log(obj2.name) // 小明
 console.log(obj1.name) // 小红
  • es6 写法
 let obj1 = {
     name: "小明",
     age: 17
 }   
 function simpleClone(obj) {
   var cloneObj = {}
   // for(let key of Object.keys(obj1)) {
   //   cloneObj[key] = obj1[key]
   // }
   for(let [key,value] of Object.keys(obj1)) {
       cloneObj[key] = value
   }
   return cloneObj
 }
 let obj2 = simpleClone(obj1)
 obj1.name = "小红"
 console.log(obj2.name) // 小明
 console.log(obj1.name) // 小红

深拷贝

  • 利用递归层层拷贝

 let obj1 = {
   a: 1,
   b: 3,
   c: {
     e: {
       f: 8
     },
       g: 4
   },
   h: 7
  }
function deepClone(obj,cloneObj) {
var cloneObj = cloneObj || {}
for(let i in obj) {
 if(typeof obj[i]=== 'object' && obj[i] !== null) {
   cloneObj[i] = {}
   deepClone(obj[i],cloneObj[i])
 } else {
   cloneObj[i] = obj[i]
 }
}
return cloneObj
}
let obj2 = deepClone(obj1)
obj1.c.g = 10
console.log(obj2.c.g) 

  • 利用 JSON.parse() 和 JSON.stringify 先将其转化为字符串,在重新转化为对象
	 let obj1 = {
       a: 1,
       b: 3,
       c: {
         e: {
           f: 5,
           i: [1,2,4,5]
         },
         g: 4
       },
       h: 7
     }
    function deepClone(obj,cloneObj) {
    // 利用 JSON.parse() 和 JSON.stringify  先将其转化为字符串,在重新转化为对象
      return JSON.parse(JSON.stringify(obj))
    }
    let obj2 = deepClone(obj1)
    obj1.c.e.i.push(10)
    console.log(obj1);
    console.log(obj2)