前言
-
JS数据类型共分为两种:
- 基本类型:boolean,undefind,null,number,string;
基本类型的数据保存在栈(stack)内存中,它们的值直接存储在变量访问的位置。 - 引用类型:object,array,function;
引用类型的数据保存在堆(heap)内存中,它们的值是一个指针,指向存储在堆内存中的对象(JavaScript不允许直接访问内存中的位置)。
堆内存用于存放由new创建的对象,栈内存存放一些基本类型的变量和对象的引用变量。
- 基本类型:boolean,undefind,null,number,string;
对比
先定义一个包含两种数据类型的初始对象 obj :
let obj = {
test1: a, // 基本类型数据 ( boolean || undefind || null || number || string )
test2: { // 引用类型数据 ( array || function || object )
test3: b,// 基本类型数据
test4: { // 引用类型数据
……
},
},
}
-
浅拷贝:
将要拷贝的引用类型数据遍历一层或者多层(不包括全部),转化为基本类型,然后建立新的对象存储- 直接赋值
let obj_eval; 如果给obj_eval赋值为 基本类型 数据,修改obj_eval不会影响obj.test1 obj_eval = obj.test1; obj_eval = 3; console.log(obj.test1); /** obj.test1 = a **/ // 如果给obj_eval赋值为 引用类型 数据,修改obj_eval也会同时修改obj.test2(因为引用类型数据保存的是一个指向栈内存的指针,所以修改任何一个拷贝的数据都会修改保存在内存中的数据) obj_eval = obj.test2; obj_eval.test3 = b1; obj_eval.test4 = b2; console.log(obj.test2); /** obj.test2 = { test3: b1, test4: b2, } **/ - 拷贝一层或者多层(不包括全部)
直接赋值引用类型的数据会引起原数据的改变,所以需要新建一个对象,然后遍历获得原始数据的属性名称和值,再绑定到新建的对象中再返回这个对象。 //新建一个拷贝对象 let obj_shallow_copy; //定义方法遍历原数据的属性名称和值 并新建一个临时对象备份存储 然后返回 function shallow_copy(obj) { let obj_copy = {}; for (let prop in obj) { if (obj.hasOwnProperty(prop)) { obj_copy[prop] = obj[prop]; } } return obj_copy; }; //赋值给新建的对象 obj_shallow_copy = shallow_copy(obj); //可多次调用该函数 obj_shallow_copy.test1 = a1; obj_shallow_copy.test2 = b1; console.log(obj); console.log(obj_shallow_copy) /** obj = { test1: a, test2: b1, }; obj_shallow_copy = { test1: a1, test2: b1, } **/ - 直接赋值
-
深拷贝:
将要拷贝的引用类型数据全部遍历递归,转化为基本类型,然后建立新的对象存储
let obj_deep_copy = deep_copy(obj);
//定义深拷贝方法
function deep_copy(obj) {
//先判断obj是否为引用类型
if(obj === null || typeof obj !== 'object'){
return obj;
}
//再判断obj是引用类型中的哪一类
let obj_copy;
if(obj instanceof Array){
obj_copy = [];
for(let i=0;i<obj.length;i++){
obj_copy.push(deep_copy(obj[i])); //递归
};
}else if(obj instanceof Object){
obj_copy = {};
for(let item in obj){
obj_copy[item] = deep_copy(obj[item]); //递归
}
};
return obj_copy;
}
obj_deep_copy.test1 = a1;
obj_deep_copy.test2 = b1;
console.log(obj);
console.log(obj_shallow_copy);
/**
obj = {
test1: a,
test2: b,
};
obj_shallow_copy = {
test1: a1,
test2: b1,
};
**/
更多深拷贝方法参考:深入剖析 JavaScript 的深复制