数据类型分为基本数据类型和引用类型
基本类型:let str = "123"; let numberNum = 5;
str , numberNum 均为引用数据类型 undefined、null、number、string、boolean Symbol
引用类型:let obj = { aaa:"123", bbb:'456', }; let arr = [1,2,3,4,5,6]
obj 为引用数据类型
深拷贝浅拷贝
- 深拷贝:深拷贝是开辟新的内存,将原始数据重新复制一份。
基本数据类型只要复制,一定开辟出一块新的内存
let str = '123';
let str2 = str; // 开辟新的内存,用来存贮str2,此时str与str2是独立的
str = '456'
console.log(str,str2) // 456 123
- 浅拷贝:并没有开辟新内存,只是将指针指向原来的数据。
let obj = { aaa:"123",bbb:'456', }
let obj2 = obj; // 此操作进行了浅拷贝,obj2的指针和obj的指针均指向{aaa:"123",bbb:"456"};
obj.aaa = '999'; // 改变obj.aaa这个数据
obj2.bbb = '111' // 改变obj2.bbb这个数据
console.log(obj,obj2); // {aaa: "999", bbb: "111"} {aaa: "999", bbb: "111"} obj与obj2均指向的是同一组数据
将引用数据类型的数据执行深拷贝操作:
一:原数组里的数据不包含引用类型
eg:let arr = [1,2,3,4,5,6]
// 方法一:
let arr2 = [...arr]; // 使用拓展运算符
// 方法二:
let arr2 = Object.assign([],arr); // 使用assign()
// 方法三:
let arr2 = [].concat(arr); // 使用concat()
// 方法四:
let arr2 = arr.slice(0); // 使用slice()
arr[0] = 9
console.log(arr,arr2) // [9, 2, 3, 4, 5, 6] [1, 2, 3, 4, 5, 6]
二:原数组里的数据有引用类型
let arr1 = [1 , 2 , 3 , {"name" : "张小二"} , {"sex" : "male"}]; //原数组
window.onload = function (){
let arr1 = [1 , 2 , 3 , {"name" : "张小二"} , {"sex" : "male"}];
// 方法一:
let arr2 = cloneObj(arr1); // 递归操作
// 方法二:
let arr2 = JSON.parse(JSON.stringify(arr1)); // 利用 JSON.parse JSON.stringify
// 注意:这种方法拷贝后的数组会丢失原数组中定义的方法和数组原型中定义的方法。
arr1[3].name = "张小三"
console.log(arr1,arr2); // [1 , 2 , 3 , {"name" : "张小三"} , {"sex" : "male"}] [1 , 2 , 3 , {"name" : "张小二"} , {"sex" : "male"}]
}
let cloneObj = function(obj){
let str, newobj = obj.constructor === Array ? [] : {};
if(typeof obj !== 'object'){
return;
} else if(window.JSON){
str = JSON.stringify(obj), //系列化对象
newobj = JSON.parse(str); //还原
} else {
for(var i in obj){
newobj[i] = typeof obj[i] === 'object' ?
cloneObj(obj[i]) : obj[i];
}
}
return newobj;
};