深拷贝和浅拷贝

88 阅读1分钟

深拷贝和浅拷贝的核心是数据类型在内存中存储的地方

基本数据类型

基本数据类型的值都是存储在栈中的,操作后返回的都是新的值。

我们定义一个基本数据类型

let str1 = 1;
// 把str1进行一个拷贝赋值
let str2 = str1;

赋值前

image.png 赋值后

image.png 它们在栈内存中是独立存储的,赋值后互不影响

引用数据类型

引用数据类型的数据源放在堆内存中,通过指针指向数据源,指向数据源的指针是放在栈内存中。引用数据类型的拷贝是将指向数据源的指针进行一个拷贝赋值

let obj = {name: 'zhangsan', age: 18};
let obj2 = obj;

赋值前

image.png 赋值后

image.png 当我们修改数据之后obj和obj2的值都会改变

obj.name = 'lisi';

image.png 引用数据深拷贝需要将数据源进行一个拷贝

let obj = {name: 'zhangsan', age: 18};
let obj2 = {};
obj2.name = obj.name;
obj2.age = obj.age;

image.png

按照这种思路实现一个深拷贝方法


function cloneDeep (data) {
   /*
       判断数据类型
       只处理需要深拷贝的类型 (Array, Object, Set, Map, Date);
   */
    
    switch (data.constructor) {
        case Array: 
        
         return data.reduce((p, c) => {
             return [...p, c];
         }, []);
         case Object:
         return Object.keys(data).reduce((p, c) => {
             return {
                 ...p,
                 [c]: data[c]
             }
          }, {});
         case Set: 
             let set = new Set();
             data.forEach(item => {
                 set.add(item);
             });
             
         return set;
         case Map: 
             let m = new Map();
           return Object.keys(data).forEach(item => {
                  m.set(item, data[item])
           });
         return m;
         case Date: 
             return new data.constructor(data);
         return;
    }
    
    
}