1.什么是深拷贝和浅拷贝?
因为javascript有原始值和引用值之分,所以当浅拷贝复制数组或者对象的时候就是复制的引用,这样复制后的两个值会相互影响,深拷贝则相当于重新开辟了一快内存去存储复制的值,两个不会互相影响。
2.数组
- 数组的浅拷贝
{
let arr = [1,2,3,4,5];
let copyArr = arr;
console.log(arr); //1 2 3 4 5
console.log(copyArr); //1 2 3 4 5
//修改arr会印象copyArr里面的值
arr.push('red');
console.log(arr); //(6) [1, 2, 3, 4, 5, "red"]
console.log(copyArr); //(6) [1, 2, 3, 4, 5, "red"]
}
显然这并不是我们想要的结果
- 深拷贝1
{
var arr = [1, 2, 3, 4, 5,'red',[{name:'kjh',id:1}],null,undefined]
function copyArr(arr) {
let res = []
for (let i = 0; i < arr.length; i++) {
res.push(arr[i])
}
return res
}
var arr2 = copyArr(arr);
console.log(arr); //(9) [1, 2, 3, 4, 5, "red", Array(1), null, undefined]
console.log(arr2); //(9) [1, 2, 3, 4, 5, "red", Array(1), null, undefined]
//修改arr2
arr2.push('red');
console.log(arr); //(9) [1, 2, 3, 4, 5, "red", Array(1), null, undefined]
console.log(arr2); //(10) [1, 2, 3, 4, 5, "red", Array(1), null, undefined, "red"]
}
- 深拷贝2
{
//slice()
//slice() 从当前数组截取部分元素形成一个新的数组。
var arr = [1, 2, 3, 4, 5,'red',[{name:'kjh',id:1}],null,undefined]
var arr2 = arr.slice(0);
console.log(arr) //(9) [1, 2, 3, 4, 5, "red", Array(1), null, undefined]
console.log(arr2) //(9) [1, 2, 3, 4, 5, "red", Array(1), null, undefined]
arr2.push("red")
console.log(arr) //(9) [1, 2, 3, 4, 5, "red", Array(1), null, undefined]
console.log(arr2) //(10) [1, 2, 3, 4, 5, "red", Array(1), null, undefined, "red"]
}
- 深拷贝3
{
//concat我们只要连接它自己,即可完成数组的深拷贝。代码如下:
var arr = [1, 2, 3, 4, 5,'red',[{name:'kjh',id:1}],null,undefined]
var arr2 = arr.concat();
console.log(arr);//(9) [1, 2, 3, 4, 5, "red", Array(1), null, undefined]
console.log(arr2);//(9) [1, 2, 3, 4, 5, "red", Array(1), null, undefined]
arr2.push('red');
console.log(arr);//(9) [1, 2, 3, 4, 5, "red", Array(1), null, undefined]
console.log(arr2);//(10) [1, 2, 3, 4, 5, "red", Array(1), null, undefined, "red"]
}
3.对象
- 对象的浅拷贝
{
let obj = {
name:'kjh',
age:20,
book:['flowers','sansum'],
add(){
console.log('123');
}
}
let copyObj = obj;
console.log(obj); //{name: "kjh", age: 20, book: Array(2), add: ƒ}
console.log(copyObj); //{name: "kjh", age: 20, book: Array(2), add: ƒ}
copyObj.name = "浅拷贝";
console.log(obj); //{name: "浅拷贝", age: 20, book: Array(2), add: ƒ}
console.log(copyObj); //{name: "浅拷贝", age: 20, book: Array(2), add: ƒ}
}
- 对象的深拷贝1
{
//for 循环
let obj = {
name:'kjh',
age:20,
book:['flowers','sansum'],
add(){
console.log('123');
}
}
let copyObj = clone(obj);
function clone(obj){
let res = {};
for(let i in obj){
res[i] = obj[i]
}
return res;
}
console.log(obj);//{name: "kjh", age: 20, book: Array(2), add: ƒ}
console.log(copyObj);//{name: "kjh", age: 20, book: Array(2), add: ƒ}
copyObj.name = '深拷贝';
console.log(obj);//{name: "kjh", age: 20, book: Array(2), add: ƒ}
console.log(copyObj);//{name: "深拷贝", age: 20, book: Array(2), add: ƒ}
}
- 对象的深拷贝2
{
let obj = {
name:'kjh',
age:20,
book:['flowers','sansum'],
add(){
console.log('123');
}
}
//使用递归的方式实现数组、对象的深拷贝
function deepClone1(obj) {
//判断拷贝的要进行深拷贝的是数组还是对象,是数组的话进行数组拷贝,对象的话进行对象拷贝
var objClone = Array.isArray(obj) ? [] : {};
//进行深拷贝的不能为空,并且是对象或者是
if (obj && typeof obj === "object") {
for (key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key] && typeof obj[key] === "object") {
objClone[key] = deepClone1(obj[key]);
} else {
objClone[key] = obj[key];
}
}
}
}
return objClone;
}
let obj2 = deepClone1(obj);
console.log(obj2);//{name: "kjh", age: 20, book: Array(2), add: ƒ}
console.log(obj); //{name: "kjh", age: 20, book: Array(2), add: ƒ}
obj2.age = 100;
console.log(obj2);//{name: "kjh", age: 100, book: Array(2), add: ƒ}
console.log(obj); //{name: "kjh", age: 20, book: Array(2), add: ƒ}
}
- 对象的深拷贝3
{
//用JSON.stringify把对象转成字符串,再用JSON.parse把字符串转成新的对象。
let obj = {
name:'kjh',
age:20,
book:['flowers','sansum'],
add(){
console.log('123');
}
}
let obj2 = JSON.parse(JSON.stringify(obj));
console.log(obj);//{name: "kjh", age: 20, book: Array(2), add: ƒ}
console.log(obj2);//{name: "kjh", age: 20, book: Array(2)}
obj2.name = 'JSON深拷贝';
console.log(obj);//{name: "kjh", age: 20, book: Array(2), add: ƒ}
console.log(obj2);//{name: "JSON深拷贝", age: 20, book: Array(2)}
//json拷贝不能拿到对象中的方法。
}