首先,先交代下,克隆只针对对象,数组,函数等复杂数据.
先看,浅拷贝,浅拷贝就是将栈内存中的引用复制一份,赋给一个新变量,本质上两个指向堆内存中的同一个地址,内容也相同,其中一个内容变化了的话,另一个也变化.
var ljy={ name:"li jingyi", age:23, address:{city:"chengdu", strict:"pidu"} } function clone(oldObj){ if(oldObj==null){return null}; if(typeof oldObj!=="Object"){ return oldObj;} var newObj =Array.isArray(oldObj)?[]:{}; for (var key in oldObj){ newObj[key] = oldObj[key]; } return newObj } var ljy2 = clone(ljy); console.log(ljy===ljy2);//true ljy.name='yeeyee'; console.log(ljy2.name)//yeeyee
很明显可以看出,改变其中一方的属性的值,另一方也会改变.
接下来我们看看深拷贝的实现:
function deepclone(oldObj){ var newObj = Array.isArray(oldObj)?[]:{}; for(var key in oldObj){ if(typeof oldObj[key] !=='object'){ newObj[key] =oldObj[key] }else{ newObj[key]=deepclone(oldObj[key]) } } return newObj; } var ljy={ name:"li jingyi", age:23, address:{city:"chengdu", strict:"pidu strict"} } var yee =deepclone(ljy); console.log(ljy===yee)//false yee.sname="Jerry"; yee.address.strict="Wuhou strict"; console.log(ljy.name)//还是li jingyi 原对象没变 console.log(ljy.address.strict)//还是pidu stict原对象没变
利用了递归的思想来实现深拷贝.首先,用isArray函数来判断是否为数组.之后判断oldObj中的元素通过typeof中所显示的是否为object(typeof下文会详细介绍),是的话实现深拷贝.通过代码就可以看出其与浅拷贝之间的差别.当然,还有更简单的做法,那么请看下面的代码:
var ljy={ name:"li jingyi", age:23, address:{city:"chengdu", strict:"pidu strict"} } var yee =JSON.parse(JSON.stringify(ljy)); console.log(ljy===yee)//false yee.sname="Jerry"; yee.address.strict="Wuhou strict"; console.log(ljy.name)//还是li jingyi 原对象没变 console.log(ljy.address.strict)//还是pidu stict原对象没变
我们可以使用json.parse()方法处理数据,将其转换为Javascript对象.
var jsontext='{"firstname":"White","lastname":"Tom"}'; var contact=JSON.parse(jsontext); document.write(contact.lastname +','+contact.firstname); //Output:Tom,White
JSON.stringfy()从一个对象中解析出字符串,而JSON.parse()从一个字符串中解析出JSON对象,这样亦可实现深拷贝.
前面我们,讲到了typeof,那么接下来,我再总结下:typeof、instanceof以及isArray.
typeof返回值是一个字符串,用来说明变量的数据类型,返回值分别有:string、boolean、number、function、object以及undefined.typeof在判断null,array,object以及函数实例时,得到的object,这样就会导致在判断这些数据类型的时候,得到的不是真实的数据类型.原来,看过类似的判断array怎么办的方式,那么这里判断array的话,是可以使用instanceof以及isarray方式的.
instanceof是判断对象是谁的实例,这里的实例就牵扯了对象的继承,它的判断,就是根据原型链进行搜寻,在对象obj1的原型链上,若存在另一个对象obj2的原型属性,那么表达式表达式obj1 instanceof obj2返回值为true否则为false.
这里再说下上面浅拷贝深拷贝代码中用到的Arrary.isArray函数,用于确定传递的值是否是一个array,而且在检测Array实例时,Array.isArray优于instanceof,因为Array.isArray能检测出iframes.