前端深拷贝和浅拷贝的原理及应用

1.1 数据类型对拷贝的作用

1.11 数据类型:

(1)基础数据类型(primitive data types):

基础数据类型:简单的数据端,基础类型的数据有Number,Null,Boolean,Number and String。这五种基础类型可以按值访问,可以直接操作保存在变量的实际值(文字来源:JavaScript高级程序设计)

前端深拷贝和浅拷贝的原理及应用_第1张图片


 let test1 = "123";
   let test2 = test1;
   window.console.log("变化之前")
   window.console.log(`test1-${test1}`)
   window.console.log(`test2-${test2}`)
 
   test2 = "321";
   window.console.log("变化之后");
  window.console.log(`test2-${test2}`)
  window.console.log(`test1-${test1}`)



前端深拷贝和浅拷贝的原理及应用_第2张图片

(2)引用数据类型(Composite data types):

引用数据类型数据是指那些可能多个值构成的对象,有Array,Object等,引用类型值保存在堆内存中,JavaScript不允许直接访问内存中的位置,也不能直接操作对象的内存空间。操作对象时是直接操作对象的引用,而不是真正对象,所以会有深拷贝和浅拷贝的问题 (文字来源:JavaScript高级程序设计)

前端深拷贝和浅拷贝的原理及应用_第3张图片

2.1 浅拷贝

浅拷贝赋值的变量,会同时指向同一个栈内存地址下的值,会影响所以变量下的赋值
前端深拷贝和浅拷贝的原理及应用_第4张图片


  //引用数据类型,只能拿到内存里面的引用
  let testObj1 = {
      name:"testObject"
  }
  let testObj2 = testObj1
  window.console.log("变化之前前");
  window.console.log("testObj1");
  window.console.log(testObj1)
  window.console.log("testObj2");
  window.console.log(testObj1)
  testObj2.name = "testObj2";
  window.console.log("变化之后");
  window.console.log("testObj1");
  window.console.log(testObj1)
  window.console.log("testObj2");
  window.console.log(testObj1)



前端深拷贝和浅拷贝的原理及应用_第5张图片

3.1 深度拷贝

深拷贝不会拷贝引用类型的引用,而是将引用类型的值全部拷贝一份,形成一个新的引用类型,这样就不会发生引用错乱的问题,使得我们可以多次使用同样的数据,而不用担心数据之间会起冲突
前端深拷贝和浅拷贝的原理及应用_第6张图片

3.2 使用方法:

3.21 方案一:使用Object.assign(target, source)方法

 let  testDeepObj1 = {
    name:"testDeepObject"
}
let  testDeepObj2 =   Object.assign({},testDeepObj1);
window.console.log("变化前")
window.console.log("testDeepObj1");
window.console.log(testDeepObj1);
window.console.log("testDeepObj2");
window.console.log(testDeepObj2);
testDeepObj2.name = "111"
window.console.log("变化后");
window.console.log("testDeepObj1");
window.console.log(testDeepObj1);
window.console.log("testDeepObj2");
window.console.log(testDeepObj2);


前端深拷贝和浅拷贝的原理及应用_第7张图片

3.22 方案二:使用ES6{…}

 let  testDeepObj1 = {
    name:"testDeepObject"
}
let  testDeepObj2 = {...testDeepObj1};
window.console.log("变化前")
window.console.log("testDeepObj1");
window.console.log(testDeepObj1);
window.console.log("testDeepObj2");
window.console.log(testDeepObj2);
testDeepObj2.name = "111"
window.console.log("变化后");
window.console.log("testDeepObj1");
window.console.log(testDeepObj1);
window.console.log("testDeepObj2");
window.console.log(testDeepObj2);


3.23 方案三:把赋值的值先利用JSON.stringfy()字符串化然后复制的时候在转为JSON.parse()

let  testDeepObj1 = JSON.stringify({
    name:"testDeepObject"
})
let  testDeepObj2 = JSON.parse(testDeepObj1);
window.console.log("变化前")
window.console.log("testDeepObj1");
window.console.log(testDeepObj1);
window.console.log("testDeepObj2");
window.console.log(testDeepObj2);
testDeepObj2.name = "111"
window.console.log("变化后");
window.console.log("testDeepObj1");
window.console.log(testDeepObj1);
window.console.log("testDeepObj2");
window.console.log(testDeepObj2);


x.1 参考材料:

(1) 浅谈JS深拷贝(深克隆)@郝晨光 :

https://www.jianshu.com/p/f4329eb1bace

(2)JavaScript高级程序设计
(3)How to differentiate between deep and shallow copies in JavaScript

https://www.freecodecamp.org/news/copying-stuff-in-javascript-how-to-differentiate-between-deep-and-shallow-copies-b6d8c1ef09cd/

你可能感兴趣的:(JavaScript)