深拷贝与浅拷贝

302 阅读3分钟

1.浅拷贝

对象进行浅拷贝时, JavaScript内存模型中的堆内存会分配一块新内存来来对拷贝源进行浅拷贝,浅拷贝只拷贝拷贝源的一层,而拷贝源中属性值是对象的只是引用对象的内存地址。
重点: 只拷贝一层,不进行深度拷贝,对于拷贝源中的子对象只是引用对象内存地址,拷贝后对象互不影响。

Obect.assgin()

let user = {
        name: "Jason",
        age: 24,
        sex: "男",
        introdution: {
            position: "前端工程师",
            school: "xxx大学",
            email: "test@qq.com"
        }
    }
let user2 = Object.assgin({},user)
// 如上只拷贝了user对象的一层,introdution 对象并没有实现拷贝,只是对对象进行引用。

拓展符(...)

let user = {
        name: "Jason"
        age: 24,
        sex: "男",
        introdution: {
            position: "前端工程师",
            schoole: "xxx大学",
            email: "test@qq.com"
        }
     }
let user2 = {...user}
// 如上只拷贝了user对象的一层,introdution 对象并没有实现拷贝,只是对对象进行引用。

2.深拷贝

对象进行深拷贝时, JavaScript内存模型中的堆内存会分配一块新内存来对拷贝源进行深度拷贝,深拷贝会进行多层拷贝,拷贝源中的基础类型及对象都会被拷贝。拷贝源中属性值是对象的不在是引用对象的内存地址而是进行对象拷贝。拷贝后的对象互不影响。
重点: 对于拷贝源中的属性值进行深度拷贝(多层拷贝),拷贝源中的对象不再是引用内存地址。拷贝后的对象互不影响。

JSON.pares(JSON.stringify())序列化与反序列化

let user = {
        name: "Jason"
        age: 24,
        sex: "男",
        introdution: {
            position: "前端工程师",
            schoole: "xxx大学",
            email: "test@qq.com"
        }
     }
 let user2 = JSON.pares(JSON.stringify(user))
// 上述通过JSON序列化和反序列化创建了一个对象,实现了深度拷贝

递归

function copy(obj){
    // 判断传入对象的类型
    if(!obj instanceof Object) retrun obj;
    if(obj instanceof Date) new Date(obj);
    if(obj instanceof Function") return obj;
    if(obj instanceof Error) return obj;
    if(obj instanceof Set) return obj;
    if(obj instanceof Map) return obj;
    if (obj instanceof RegExp) return new RegExp(obj.source, obj.flags)
    // 上述对象判断举个例子,应该该是其他的对象类型,如下进行深拷贝处理
    const result = Array.isArray(obj) ? [] : {};
    Object.keys(obj).forEach(item = > {
        if(obj[key] instanceof Object) {
            result[key] = copy(obj[key]);
        }
        else {
            result[key] = obj[key];
        }
    }) 
    return result;
} 

// 如上通过函数递归对对象中的属性进行了深度拷贝

3.= 与深浅拷贝的区别

= 是一个赋值运算符,只是对于基本类型的引用,和对象的引用。跟深浅拷贝没有关系。深浅拷贝对对象数组进行深浅拷贝,最后会得到内部分配的块内存来存储拷贝的值。 = 赋值运算符只是将内存地址赋值给变量。

let user = {
        name: "Jason"
        age: 24,
        sex: "男",
        introdution: {
            position: "前端工程师",
            schoole: "xxx大学",
            email: "test@qq.com"
        }
     }
 let user2 = user
// = 赋值运算符将对象内存地址赋值给了user,user中存的 对象的内存地址,当user2 = user时,将user 中的存的内存地址赋值给user2