深浅拷贝详解
解释
1.复制数据的方式
2. 一般指的就是复制对象或者数组
复制有三个级别
1. 赋值
赋值以后, 两个变量操作一个对象空间
2.浅拷贝
(1) 把你的对象内的每一个数据复制一份给我
(2) 我进行修改的时候, 你不会修改
(3) 只能拷贝一层数据, 多维度数据不好使
如何实现浅拷贝 ?
(1) 我把我自己制作成和你一样的数据类型
(2) 把你内部每一个数据依次复制过来
var o2 = {}
// o1 内有什么 key, o2 内就有什么 key
for (var k in o1) {
// o1 有多少个成员, 执行多少回, k 分别是 o1 内的每一个 key
// 照样添加到 o2 内
// 在逐个复制的过程中
// 当 k === 'info' 的时候
// o1[k] 存储的是一个对象的地址, 把这个地址给到了 o2[k]
// 从此以后 o1[k] 和 o2[k] 存储的是一个地址空间
o2[k] = o1[k]
}
console.log(o1, o2)
o1.name = 'Rose'
console.log(o1, o2)
o1.info.weight = 190
console.log(o1, o2)
3. 深拷贝
(1) 把你的对象内每一个数据复制一份给我, 不管多少层维度都进行百分百赋值
(2) 两个对象完全没有任何关系
(3) 在遍历复制的过程中
判断如果你不是对象, 那么我直接复制
判断如果你是对象, 我把我的这一项也设置成对象, 然后重复遍历你的第二层对象
o1 是新对象
// o2 是原始对象
// 目的: 就是把 o2 对象内的所有内容 深拷贝 到 o1 内
function deepCopy(o1, o2) {
code run here ...
console.log('新对象 : ', o1)
console.log('原始对象 : ', o2)
// 步骤1: 要遍历原始对象
for (var k in o2) {
if (Object.prototype.toString.call(o2[k]) === '[object Object]') {
// 代码如果执行到这里, 说明 o2[k] 是一个对象数据类型
// 需要把 o1[k] 也设置成对象数据类型
o1[k] = new Object()
// 把 o2[k] 这个对象内的数据百分百深拷贝一份到 o1[k]
deepCopy(o1[k], o2[k])
} else {
o1[k] = o2[k]
}
}
}
/**
* 实现深拷贝
* @param {Object} o1 目标对象
* @param {Object} o2 原始对象
*/
function deepCopy(o1, o2) {
for (var k in o2) {
if (Object.prototype.toString.call(o2[k]) === '[object Object]') {
o1[k] = new Object()
deepCopy(o1[k], o2[k])
} else {
o1[k] = o2[k]
}
}
}
(4) 递归深拷贝
4.扩展浅拷贝
(1) 一个运算符, 展开运算符(…)
(2) 直接在一个对象内书写 …对象名
var o1 = {
name: 'Jack',
age: 18,
gender: '男',
info: { weight: 180, height: 180 }
}
var o2 = {
...o1,
address: {}
}
console.log(o1, o2)
o1.name = 'Rose'
console.log(o1, o2)
o1.info.weight = 200
console.log(o1, o2)