JS的深拷贝和浅拷贝

‍本文作者是360奇舞团开发工程师

数据类型的数据存储

在讨论深拷贝和浅拷贝之前,先来了解下Js基本数据和引用数据类型的存储问题

  • 基本数据类型:Number String Boolean Undefined Symbol Null

  • 引用类型 :Object,function,Array等

基本数据类型的值存放在栈中,在栈中存放的是对应的值;引用类型对应的值存放在堆中,在栈中存放的是指向堆内存的地址,
下面看下数据的赋值过程

  • 基本数据类型赋值是生成相同的值,两个存放在不同地址;

  • 引用类型赋值,是将对象的内存地址赋值到另一个对象,两个变量指向堆内存中同一个对象

基本数据类型的赋值过程

let t1 = 66
let t2 =t1
t1= 88
console.log("t1="+t1+"\t t2="+t2)
输出:
t1=88    t2=66

JS的深拷贝和浅拷贝_第1张图片

引用类型的赋值过程

let  obj1={
    name:"张三",
    age:6

}
let obj2 = obj1
obj1.name="zhangsan"
console.log("obj1="+JSON.stringify(obj1)+"\t obj2="+JSON.stringify(obj2))
输出:
obj1={"name":"zhangsan","age":6}         obj2={"name":"zhangsan","age":6}

JS的深拷贝和浅拷贝_第2张图片

深拷贝和浅拷贝

了解了数据类型的存储类型,那么深拷贝和浅拷贝就容易理解了

浅拷贝

浅拷贝:指的是创建新的数据,这个数据和原始数据相同,如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址

代码实现一个浅拷贝

function shallowCopy(obj) {
    let newObject ={}
    for (let key in obj) {
        if(obj.hasOwnProperty(key)){
            newObject[key] = obj[key]
        }
    }
    return newObject
}
let  p={
    name:"zhangsan",
    hobby:{
        playTime:"12年"
    }
}

let p1 = shallowCopy(p)
console.log("p1="+JSON.stringify(p1))
console.log("p=" + JSON.stringify(p))
p.hobby.playTime = "16年"
p.name="李四"
console.log("p1=" + JSON.stringify(p1))
console.log("p=" + JSON.stringify(p))
输出:
p1={"name":"zhangsan","hobby":{"playTime":"12年"}}
p={"name":"zhangsan","hobby":{"playTime":"12年"}}
p1={"name":"zhangsan","hobby":{"playTime":"16年"}}
p={"name":"李四","hobby":{"playTime":"16年"}}

深拷贝

深拷贝是开辟一个新的栈,两个对象完全相同,但是对应两个不同地址,修改任一对象不会影响另一个对象

代码实现一个深拷贝

let p = {
    name: "zhangsan",
    hobby: {
        playTime: "12年"
    }
}
function deepCopy(obj) {
    if(obj == null) return obj
    if (obj instanceof Date) return new Date(obj)
    if( obj instanceof RegExp) return RegExp(obj)
    if(typeof obj !="object") return obj
    let  targetObj ={}
    for (let key in obj) {
        if(obj.hasOwnProperty(key)){
            targetObj[key] = deepCopy(obj[key])
        }
    }
    return targetObj
}
let  p1=deepCopy(p)
console.log("p1=" + JSON.stringify(p1))
console.log("p=" + JSON.stringify(p))
p.hobby.playTime = "16年"
p.name = "李四"
console.log("p1=" + JSON.stringify(p1))
console.log("p=" + JSON.stringify(p))
输出:
p1={"name":"zhangsan","hobby":{"playTime":"12年"}}
p={"name":"zhangsan","hobby":{"playTime":"12年"}}
p1={"name":"zhangsan","hobby":{"playTime":"12年"}}
p={"name":"李四","hobby":{"playTime":"16年"}}

深拷贝和浅拷贝的区别

深拷贝和浅拷贝都创建出一个对象,但是拷贝对象属性的时候行为不一样,浅拷贝只复制指针,两个对象仍然共用一块内存,所以修改会相互影响;深拷贝出来的对象与原对象一模一样,但是不共用一块空间,修改互不影响

- END -

关于奇舞团

奇舞团是 360 集团最大的大前端团队,代表集团参与 W3C 和 ECMA 会员(TC39)工作。奇舞团非常重视人才培养,有工程师、讲师、翻译官、业务接口人、团队 Leader 等多种发展方向供员工选择,并辅以提供相应的技术力、专业力、通用力、领导力等培训课程。奇舞团以开放和求贤的心态欢迎各种优秀人才关注和加入奇舞团。

JS的深拷贝和浅拷贝_第3张图片

你可能感兴趣的:(javascript,前端,开发语言,ecmascript,vue.js)