浅拷贝只复制了地址,通过遍历的方式复制目标对象的属性,当内部存在数组和对象时,并不会被复制到新对象中,只拷贝基本数据类型,且存在新对象更改属性值时目标对象同一属性的属性值受到影响
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>Document</title></head><body><script>let target={a:10,b:2,d:['原','有','的','数','组'],c:function(){returnthis.a+this.b}}let newObj={}for(var kin target){ newObj[k]= target[k]} newObj.b=10 newObj.d.push('这是加给newObj的元素') console.log('newObj:',newObj)//newObj: {a: 10, b: 10, d: Array(6), c: ƒ}a: 10b: 10c: ƒ ()d: (6) ['原', '有', '的', '数', '组', '这是加给newObj的元素'][[Prototype]]: Object console.log('target:',target);//target: {a: 10, b: 2, d: Array(6), c: ƒ}a: 10b: 2c: ƒ ()d: (6) ['原', '有', '的', '数', '组', '这是加给newObj的元素'][[Prototype]]: Object</script></body></html>
浅拷贝还可以利用ES6的语法糖assign方法
object.assign(拷贝给谁,拷贝目标)
对象内引用数据类型的值也被拷贝,但需要用到函数递归进行拷贝
手写deepCopy函数实现深拷贝
<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>Document</title></head><body><script>functiondeepCopy(newObj,oldObj){for(var kin oldObj){let item= oldObj[k]if(iteminstanceofArray){ newObj[k]=[]deepCopy(newObj[k],item)}elseif(iteminstanceofObject){ newObj[k]={}deepCopy(newObj[k],item)}else{ newObj[k]= item}}return newObj}</script></body></html>
还可以通过JSON的stringify和parse方法实现深拷贝,但此方法的不足是无法识别函数,被拷贝对象中的方法会被忽略
let newObj = JSON.parse(JSON.stringify(oldObj))
<htmllang="en"><head><metacharset="UTF-8"><metahttp-equiv="X-UA-Compatible"content="IE=edge"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>Document</title></head><body><script>let target={a:10,b:2,d:['原','有','的','数','组'],c:function(){returnthis.a+this.b}}let newObj=JSON.parse(JSON.stringify(target)) console.log(newObj);//Object a: 10 b: 2 d: (5) ['原', '有', '的', '数', '组'] [[Prototype]]: Object</script></body></html>