JS对象的浅拷贝与深度拷贝
1、js中的6个标准类型
原始类型:Undefined、Null、Boolean、String、Number
引用类型:Object ( 最简单的引用类型var obj={} )
2、把标准类型分成了两类、这两种类型复制克隆有很大区别
原始类型:存储的是对象的实际数据( 存放在栈内存中 )
引用类型:存储的是对象的引用地址( 栈内存中存放的堆内存的地址 )
3、克隆概念
浅度克隆:原始类型为值传递、对象类型仍为引用传递
深度克隆:所有的元素与属性均完全复制、与原对象完全脱离关系( 对新对象的修改不会影响原对象 )
4、浅克隆
原始类型克隆的表现
1 var num1 = 123; 2 var num2 = num1; 3 num2 = 456; 4 console.log(num1); // 123 5 console.log(num2); // 456
常见的浅拷贝
1 var obj = { 2 a:10, 3 b:20 4 } 5 function clone(obj){ 6 var newobj = {}; 7 for(key in obj){ 8 newobj[key] = obj[key]; 9 } 10 return newobj; 11 } 12 obj2 = clone(obj); 13 console.log(obj2.a); // 10 14 obj2.a = 100; 15 console.log(obj2.a); // 100 16 console.log(obj.a); // 10
浅拷贝可以解决常见的对象、若对象内部还有对象、如下
1 var obj = { 2 a:{ 3 a1:'aa', 4 a2:'bb' 5 }, 6 b:20 7 } 8 function clone(obj){ 9 var newobj = {}; 10 for(key in obj){ 11 newobj[key] = obj[key]; 12 } 13 return newobj; 14 } 15 obj2 = clone(obj); 16 console.log(obj2.a.a1); // aa 17 obj2.a.a1 = 'cc'; 18 console.log(obj2.a.a1); // cc 19 console.log(obj.a.a1); // cc 20 // 更改了obj2的a1、obj的a1也随之改变、说明a同时被obj、obj2同时引用。那么问题来了:怎么解决?
5、深度克隆
1 var obj = { 2 a:10, 3 b:{ 4 bb:50, 5 cc:60 6 } 7 }; 8 function deepClone(obj){ 9 var result={},oClass=isClass(obj); 10 for(key in obj){ 11 var copy = obj[key]; 12 if (isClass(copy)=="Object") { 13 result[key] = arguments.callee(copy); 14 } else if(isClass(copy) == "Array"){ 15 result[key] = arguments.callee(copy); // 递归 16 }else{ 17 result[key] = obj[key]; 18 }; 19 } 20 return result; 21 } 22 // alert(isClass(undefined)); 23 function isClass(o){ 24 return Object.prototype.toString.call(o).slice(8,-1); 25 }; 26 obj2 = deepClone(obj); 27 console.log(obj2.b.bb); // 50 28 obj2.b.bb = 500; 29 console.log(obj2.b.bb); // 500 30 console.log(obj.b.bb); // 50 31 32 // Object.prototype.toString.call() 所有js类型都会得到不同的字符串 33 /* 34 为了保证对象的所有属性都被复制到,我们必须知道如果for循环以后,得到的元素仍是Object或者Array,那么需要再次循环,直到元素是原始类型或者函数为止。为了得到元素的类型,我们定义一个通用函数( isClass ),用来返回传入对象的类型。 35 */
学习笔记、欢迎路过的同学们批评&指教
居敬持志~ Coding