深度克隆和浅度克隆的最大不同之处就在于: 深度克隆出来的数据会开辟新的独立的内存空间,而浅度克隆出来的数据和原始数据共用同一个内存空间,只是多了个指向该空间的引用。
对象浅度克隆的例子:
可以看到简单的将obj对象赋值给obj1对象,修改其中一个对象引用指向的内存空间的数据,另一个对象引用指向的内存空间的数据也会发生改变,说明两个引用指向的是同一个数据,属于浅度克隆
对象深度克隆例题:
var obj = { name:'yinzhiyuan', age:12, card:['chuding','klsm'], wife:{ name:'LS', son:{ name:'xiaolei' } } } var obj1 = { }现在要将对象obj深度克隆给对象obj1
注意: 变量可以存放两种类型的值: 原始值 和 引用值
原始值代表原始数据类型的值,也叫基本数据类型,包括 Number、Stirng、Boolean、Null、Underfined。
原始变量及他们的值储存在栈中,当把一个原始变量传递给另一个原始变量时,是把一个栈房间的东西复制到另一个栈房间,且这两个原始变量互不影响。
引用值指的是复合数据类型的值,包括 Object(Array、null也是Object)、Function、Date、RegExp。
引用值是把引用变量的名称储存在栈中,但是把其实际对象储存在堆中,且存在一个指针由变量名指向储存在堆中的实际对象,当把引用对象传递给另一个变量时,复制的其实是指向实际对象的指针,此时 两者指向的 是同一个数据,若通过方法改变其中一个变量的值,则访问另一个变量时,其值也会随之加以改变;但若不是通过方法 而是通过 重新赋值 此时相当于重新开了一个房间该值的原指针改变 ,则另外一个值不会随他的改变而改变。
遍历对象 for(var prop in obj) 1 . 判断要克隆的对象中的数据是 原始值 还是 引用值 ,原始值直接赋值(function也可直接赋值),引用值还需进行下面的判断 2 . 判断是数组还是对象(1.constructor 2.instanceof 3.toString+call(推荐)) 3 . 建立相应的数组或对象 4 . 对数组或对象中的元素回到第一步进行判断(递归)
可以看到obj1对象克隆成功,且不是两个引用指向同一对象,而是两个单独的对象 当target为null时,也能输出克隆出来的对象