简介
- 浅拷贝:拷贝基本数据类型的值,但对于引用数据类型,只拷贝他在堆内存中的地址,修改新数据或者原数据都会引起原数据的改变
- 深拷贝:把所有数据都赋值到新的内存空间,是最彻底的拷贝
浅拷贝方法
1.Object.assgin()
对数据进行浅拷贝,可以将多个源对象拷贝到一个新对象里去
// 语法1
const obj2 = Object.assgin({}, obj1);
// 语法2
Object.assign(目标对象, 源对象1, 源对象2...);
重点看这个
const obj1 = {
name: 'qianguyihao',
age: 28,
desc: 'hello world',
};
const obj2 = {
name: '许嵩',
sex: '男',
};
// 浅拷贝:把 obj1 赋值给 obj2。这一行,是关键代码。这行代码的返回值也是 obj2
Object.assign(obj2, obj1);
console.log(JSON.stringify(obj2));
2.for in 方法(繁琐不推荐)
const obj1 = {
name: 'qianguyihao',
age: 28,
info: {
desc: '很厉害',
},
};
const obj2 = {};
// 用 for in 将 obj1 的值拷贝给 obj2
for (let key in obj1) {
obj2[key] = obj1[key];
}
console.log('obj2:' + JSON.stringify(obj2));
obj1.info.desc = '永不止步'; // 当修改 obj1 的第二层数据时,obj2的值也会被改变。所以 for in 是浅拷贝
console.log('obj2:' + JSON.stringify(obj2));
深拷贝方法
深拷贝就是对浅拷贝的递归
1. JSON.parse(JSON.stringify())
原理:用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象,一去一来,新的对象产生了,而且对象会开辟新的栈,实现深拷贝
let arr = [1, 3, {
username: ' kobe'
}];
let arr4 = JSON.parse(JSON.stringify(arr));
arr4[2].username = 'duncan';
console.log(arr, arr4)
这种方法虽然可以实现数组或对象深拷贝,但不能处理函数
let arr = [1, 3, {
username: ' kobe'
},function(){}];
let arr4 = JSON.parse(JSON.stringify(arr));
arr4[2].username = 'duncan';
console.log(arr, arr4)
// [ 1, 3, { username: ' kobe' }, [Function (anonymous)] ]
// [ 1, 3, { username: 'duncan' }, null ]
这是因为JSON.stringify() 方法是将一个JavaScript值(对象或者数组)转换为一个 JSON字符串,不能接受函数
2.函数库lodash
var _ = require('lodash');
var obj1 = {
a: 1,
b: { f: { g: 1 } },
c: [1, 2, 3]
};
var obj2 = _.cloneDeep(obj1);
console.log(obj1.b.f === obj2.b.f);
// false
3. for in 实现深拷贝
let obj1 = {
name: 'qianguyihao',
age: 28,
info: {
desc: 'hello',
},
color: ['red', 'blue', 'green'],
};
let obj2 = {};
deepCopy(obj2, obj1);
console.log(obj2);
obj1.info.desc = 'github';
console.log(obj2);
// 方法:深拷贝
function deepCopy(newObj, oldObj) {
for (let key in oldObj) {
// 获取属性值 oldObj[key]
let item = oldObj[key];
// 判断这个值是否是数组
if (item instanceof Array) {
newObj[key] = [];
deepCopy(newObj[key], item);
} else if (item instanceof Object) {
// 判断这个值是否是对象
newObj[key] = {};
deepCopy(newObj[key], item);
} else {
// 简单数据类型,直接赋值
newObj[key] = item;
}
}
}