您好,欢迎来到叨叨游戏网。
搜索
您的当前位置:首页关于js中的深浅拷贝和assign到底是深拷贝还是浅拷贝的争论

关于js中的深浅拷贝和assign到底是深拷贝还是浅拷贝的争论

来源:叨叨游戏网

     又到了跳槽的热门期,有很多小伙伴都问深浅克隆的问题,我面试时也问了很多关于深浅克隆和assign的问题,但能清楚的答上来的很少,还有一些做了2,3年前端对堆栈也分不清,下面是我自己的理解和一些经验。

       要理解深浅克隆首先要知道js的数据类型:字符串(String)、数字(Number)、布尔(Boolean)、数组(Array)、对象(Object)、空(Null)、未定义(Undefined)以及es6新增数据类型symbol。

举个例子:

var age = 27;
var worker = {
       name:"yyx"
          } 复制代码


所以操作的是堆还是栈就出现了深浅拷贝的问题

深浅拷贝

例:
var age = 27;
var newAge = age;
console.log(age)//------27
console.log(newAge)//---27
newAge = 72;
console.log(age)//------27
console.log(newAge)//---72

当操作的是基本类型时newAge并没有对age产生影响

例:
var worker = {
    name:"yyx"
  }
  var newWorker = worker
  console.log(worker)//-------{name:"yyx"}
  console.log(newWorker)//----{name:"yyx"}
  newWorker.name = "yu"
  console.log(worker)//-------{name:"yu"}
  console.log(newWorker)//----{name:"yu"}
当操作的是引用类型时,改变newWorker的值时worker的值也发生变化了复制代码

因为上面两个例子克隆的都只是栈,而克隆的引用类型还指向同一个堆所以改变其中一个的数据,别外的也会发生改变,这就是浅克隆,如图:


而想要完成深克隆,即worker和newWorker互不影响,最常用的就是方法就是递归:

function deepClone(obj) {
  if (typeof obj != "object") {
    return obj
  }
  var newObj = {};
  for (var i in obj) {
    newObj[i] = deepClone(obj[i]);
  }
  return newObj
}
var worker = {
    name:"yyx",
    age:"27"
}
var newWorker = deepClone(worker)
console.log(worker)//----{name:"yyx", age:"27"}
console.log(worker)//----{name:"yyx", age:"27"}
newWorker.name = "yu"
console.log(worker)//----{name:"yyx", age:"27"}
console.log(newWorker)//-{name:"yu", age:"27"}
此时改变newWorker的值时就不会对worker产生影响复制代码

此时newWorker指向了新的堆,更改时不会对worker产生影响

如图:


此外还有别的方法实现深克隆var obj1 = JSON.parse(JSON.stringify(obj))这几种都是常用的对象深克隆方法

ES6新增方法assign()

assign(obj,...obj)方法接受多个参数,第一个参数为拷贝目标,剩余参数是拷贝源。此方法可以将...obj中的属性复制到obj中,名字相同的属性会覆盖,实现了对象拷贝

有意思的是assign对只有1层的对象实现的是深拷贝,多层对象实现的是浅拷贝

 

例1:
var worker = {
  name:"yyx"
 }
 var newWorker = Object.assign({},worker)
 newWorker.name = "yu"
 console.log(worker)//----{name:"yyx"}
 console.log(newWorker)//-{name:"yu"}
新的对象newWorker并没有对worker产生影响

例2:
var worker = {
  name:"yyx",
  info:{
    age:27
  }
 }
 var newWorker = Object.assign({},worker)
 newWorker.info.age = 20
 console.log(worker.info.age)//----20
 console.log(newWorker.info.age)//-20
新的对象newWorker改变影响到了worker

复制代码

由上面例子可以看出来,assign的坑,这也是面试时面试官为什么都喜欢问assign是深克隆还是浅克隆的原因


因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- gamedaodao.net 版权所有 湘ICP备2024080961号-6

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务