本文作者是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
引用类型的赋值过程
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}
深拷贝和浅拷贝
了解了数据类型的存储类型,那么深拷贝和浅拷贝就容易理解了
浅拷贝
浅拷贝:指的是创建新的数据,这个数据和原始数据相同,如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址
代码实现一个浅拷贝
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 objif (obj instanceof Date) return new Date(obj)if( obj instanceof RegExp) return RegExp(obj)if(typeof obj !="object") return objlet 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 等多种发展方向供员工选择,并辅以提供相应的技术力、专业力、通用力、领导力等培训课程。奇舞团以开放和求贤的心态欢迎各种优秀人才关注和加入奇舞团。