1.在做ife2015 task2 的题目,关于深度克隆一个目标对象,返回一个完整的拷贝。像我这种没学多少的,以为就是对这个目标从新赋值给一个变量,好比
var obj1={a:1,b:2}; var obj2=obj1;
我以为这样就算把obj1克隆了一份到obj2了,但是实际上你给obj2添加多一个属性好比
obj2.c=3;
这样我obj2也就等于{a:1,b:2,c:3},不仅仅是obj多了一个属性,obj1也多了一个c属性,
因为他们其实指向同一个堆内存对象,就是存放的资料在一个地方所以会共享。
所以进行深度克隆就是为了让他们有各自的家,也就是需要生成一个副本,生成一个一模一样但是地方不同的房子;
2.那我们就要了解什么样的数据克隆才需要副本,刚刚我们了解到,需要副本是因为直接赋值的数据会共享,那么我们就要了解哪些会数据共享,引用类型就是这样的
在说引用类型前 , 我们先来说下数据类型,数据类型区分我们都知道,那他们的值的数据是保存在哪的,这就引出了 值类型和引入类型;分成这两类当然是因为他们功能不同啦
值类型:存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。
这样的话我没系统学过计算机不好理解,,所以就用下面的话来通俗的说下
变量的交换等于在一个新的地方按照连锁店的规范标准(统一店面理解为相同的变量内容)新开一个分店,这样新开的店与其它旧店互不相关、各自运营。
引用类型:存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point),指向存储对象的内存处。
变量的交换等于把现有一间店的钥匙(变量引用地址)复制一把给了另外一个老板,此时两个老板同时管理一间店,两个老板的行为都有可能对一间店的运营造成影响。
引用了http://www.jb51.net/article/71537.htm中的语句
具体来讲
(1)值类型:数值、布尔值、null、undefined string(比较特殊)
(2)引用类型:对象、数组、函数。 Date / Function / RegExp比较少用
所以就是除了值类型的以外,剩下的引用类型要深度可能的话不能直接赋值,而是要创建副本
functioncloneObject (src) {//对于基本数据类型,只要直接返回即可if(src ==null||typeofsrc != 'object') {returnsrc;
}//对于对象分为以下三种情况//对于Date等引用类型的数据,需要考虑调用构造函数重新构造,直接赋值依然会有引用问题(不是真正的clone引用变量)//以Date为例if(srcinstanceofDate) {varclone =newDate(src.getDate());returnclone;
}//对于数组,需要遍历,这样可以保证在在Array对象上扩展的属性也可以正确复制if(isArray(src)) {varclone =[];for(vari = 0; i < src.length; i++) {
clone[i]=cloneObject(src[i]);
}returnclone;
}//对于其他object,同样也需要遍历if(srcinstanceofObject) {varclone ={};for(varkeyinsrc) {if(src.hasOwnProperty(key)) {//忽略掉继承属性,只取属于它本身的属性clone[key] =cloneObject(src[key]);
}
}returnclone;
}
}