一、赋值
- 只要是引用数据类型, 那么在赋值的时候, 就是引用地址的传递
// 赋值:字符串
const s1 = '123';
let s2 = s1; // 赋值
console.log(s2 === s1); // true
s2 = '456';
console.log(s1); // 123
console.log(s2); // 456

let o1 = { a: 1 };
let o2 = o1; // 赋值
console.log(o2 == o1);
o2.a = 999;
console.log(o1);
console.log(o2);

let a1 = [1, 2, 3];
let a2 = a1; // 赋值
console.log(a2 == a1);
a2[0] = 999;
console.log(a1);
console.log(a2);

二、浅拷贝
- 遍历对象拿到对象的每一个key与value,然后赋值给另外一个对象
- 如果所有的value都是基本数据类型, 那么浅拷贝完成之后, 修改新对象不会影响到老对象
- 如果 value 有引用数据类型(出现了多层数据结构), 那么浅拷贝只能拷走第一层数据结构, 多层的没有办法处理
- 注意:深浅拷贝一定是引用数据类型,对象, 数组, 函数(基本只有对象和数组)
1、浅拷贝的实现
let o1 = {
a: 1,
b: 2,
c: 3,
d: {
d1: '001',
d2: '002',
d3: '003'
}
}
let o2 = {}
for (let key in o1) {
// 遍历o1对象所有的key, 然后赋值给对象o2
// console.log(key, o1[key]);
o2[key] = o1[key];
}
console.log(o1); // {a: 1, b: 2, c: 3}
console.log(o2); // {a: 1, b: 2, c: 3}
console.log(o1 === o2); // false

let o1 = {
a: 1,
b: 2,
c: 3,
d: {
d1: '001',
d2: '002',
d3: '003'
}
}
let o2 = {}
for (let key in o1) {
// 遍历o1对象所有的key, 然后赋值给对象o2
// console.log(key, o1[key]);
o2[key] = o1[key];
}
o2.b = 999;
console.log(o1 === o2); // false
console.log(o1); // {a: 1, b: 2, c: 3}
console.log(o2); // {a: 1, b: 999, c: 3}

let o1 = {
a: 1,
b: 2,
c: 3,
d: {
d1: '001',
d2: '002',
d3: '003'
}
}
let o2 = {}
for (let key in o1) {
// 遍历o1对象所有的key, 然后赋值给对象o2
// console.log(key, o1[key]);
o2[key] = o1[key];
}
o2.d.d1 = 'QF666'
console.log(o1 === o2);
console.log(o1);
console.log(o2);

2、JS提供的浅拷贝
- Object.assign(新对象, 原始对象)
- 将原始对象中所有的key,全部浅拷贝到新对象中, 然后返回一个对象
let o1 = {
a: 1,
b: 2,
c: 3,
d: {
d1: '001',
d2: '002',
d3: '003'
}
}
let o2 = Object.assign({}, o1);
console.log(o1);
console.log(o2);

三、深拷贝
- 不管数据有多少层数据结构, 百分百复制出来一份,一摸一样但是毫不相关的数据
let o1 = {
a: 1,
b: 2,
c: 3,
d: {
d1: '001',
d2: '002',
d3: '003'
}
}
let o2 = {}
function deepClone(target, origin) {
// 将origin完全百分百的复制出来一份, 到target中
for (let k in origin) {
// console.log(k, origin[k])
if (origin[k].constructor === Object) {
target[k] = {}
deepClone(target[k], origin[k])
} else if (origin[k].constructor === Array) {
target[k] = []
deepClone(target[k], origin[k])
} else {
target[k] = origin[k]
}
}
}
deepClone(o2, o1);
console.log(o1 === o2);
console.log(o1);
console.log(o2);

let o1 = {
a: 1,
b: 2,
c: 3,
d: {
d1: '001',
d2: '002',
d3: '003'
}
}
let o2 = {}
function deepClone(target, origin) {
// 将origin完全百分百的复制出来一份, 到target中
for (let k in origin) {
// console.log(k, origin[k])
if (origin[k].constructor === Object) {
target[k] = {}
deepClone(target[k], origin[k])
} else if (origin[k].constructor === Array) {
target[k] = []
deepClone(target[k], origin[k])
} else {
target[k] = origin[k]
}
}
}
deepClone(o2, o1);
o2.d.d2 = 'QF666';
console.log(o2);
console.log(o1);

2、JS中提供的方法
let o1 = {
a: 1,
b: 2,
c: 3,
d: {
d1: '001',
d2: '002',
d3: '003'
}
}
let o2 = JSON.parse(JSON.stringify(o1));
o2.d.d3 = '9999999';
console.log(o1);
console.log(o2);
