(五) js中的深浅拷贝
无论是深拷贝还是浅拷贝都是创建一个新的对象
1. 浅拷贝
浅拷贝是创建一个新对象, 这个对象有原始对象属性值的一份精确拷贝. 如果属性是基本类型, 拷贝的就是基本类型的值, 如果属性时引用类型, 拷贝的就是内存地址
function shallow(obj) {
if (typeof obj !== 'object' || obj === null) return obj
var shallowObj = {}
for (let i in obj) {
if (obj.hasOwnProperty(i)) {
shallowObj[i] = obj[i]
}
}
return shallowObj
}
var person = {
name: '张三',
age: 18,
hobbies: ['唱歌', ['打游戏', '看电影']]
}
var p = shallow(person)
p.name = '李四'
p.hobbies[0] = '跳舞'
console.log('p: ', p);
console.log('person: ', person);
2. 深拷贝
深拷贝是将一个对象从内存中完整的拷贝一份出来, 从堆内存中开辟一个新的区域存放新对象, 彼此完全独立
function deepClone(obj) {
var cloneObj = {}
if (typeof obj !== 'object' || obj === null) return obj
for (let i in obj) {
if (obj.hasOwnProperty(i)) {
cloneObj[i] = deepClone(obj[i])
}
}
return cloneObj
}
var person = {
name: '张三',
age: 18,
hobbies: ['唱歌', ['打游戏', '看电影']]
}
var p = shallow(person)
p.name = '李四'
p.hobbies[0] = '跳舞'
console.log('p: ', p);
console.log('person: ', person);
但是上面的深拷贝还有一个问题, 那就是对于 Date、RegExp
这两个对象是无法进行拷贝的
var a = deepClone({ date: new Date() })
console.log(a);
因此我们需要完善一下
function deepClone(obj) {
var cloneObj = {}
// 添加如下两行判断
if (obj instanceof Date) return new Date()
if (obj instanceof RegExp) return new RegExp()
if (typeof obj !== 'object' || obj === null) return obj
for (let i in obj) {
if (obj.hasOwnProperty(i)) {
cloneObj[i] = deepClone(obj[i])
}
}
return cloneObj
}
3. 总结对比
是否和原始值指向同一对象 | 第一层数据为基本类型 | 第一层数据为引用类型 | |
---|---|---|---|
赋值(复制) | 是 | 改变会使原始值一同改变 | 改变会使原始值一同改变 |
浅拷贝 | 不是 | 不会改变原始值 | 改变会使原始值一同改变 |
深拷贝 | 不是 | 不会改变原始值 | 不会改变原始值 |
仅记录自己的学习总结,如有错误,还请评论指正~