1.浅拷贝
这个很简单,浅拷贝拷贝的就是地址,其中一个修改另一个也会改变。
浅拷贝拷贝的是地址,只会拷贝最外层的对象(即只会拷贝一层)
<script>const obj={uname:'111',age:18}const os=obj//os就和obj对象一样,但是我们修改os中的obj也会跟随改变os.uname='22'console.log(obj)//obj的uname也会改变</script>
拷贝对象:Object.assign(os,obj) || const os={…obj}
拷贝数组:Array.prototype.concat() || […arr]
存在问题:对象内还有对象的时候进修改内部对象的属性修该其中一个另一个对象也会变化
<script>const obj={uname:'111',age:18,user:{ baby:'内部'}}Object.assign(os,obj)//os就和obj对象一样,但是我们修改os中的obj也会跟随改变os.user.baby='22'console.log(obj)//obj.user.baby也会改变</script>
2.深拷贝
深拷贝拷贝的是值,独立新创建一个地址,两个地址互不影响。
有三种方法 递归函数、外部插件lodash.js百度就能找到官网 JSON.stringify()
2.1使用递归函数进行实现
(函数的内部调用自己就是递归)function fn(){fn() return 条件} 必须有结束条件
<script>const obj={uname:'111',age:18,hobby:['哈哈','呵呵']user:{ baby:'内部'}}const os={}function deepCopy(newObj,oldObj){for(let k in oldObj){//处理对象内有数组的情况 要先处理数组后处理对象,因为数组属于对象if(oldObj[k] instanceof Array){//声明一个新的空数组让遍历的元素放到空数组中newObj[k]=[]//这里可以写循环,但是我们函数内本身就有for in循环直接俄传参数就可以//难点1deepCopy(newObj[k],oldObj[k])}else if(oldObj[k] instanceof Object){//处理对象内套数组//我们新对象得中得某一个对象就是 newObj[k]={}newObj[k]={}//难点2deepCopy(newObj[k],oldObj[k])}else{//k 属性名 oldObj[k]属性值//newObj[k]就是 os.unamenewObj[k]=oldObj[k]}}}deepCopy(os,obj)</script>
代码种比较难理解的应该是两次函数的自己调用,其实就是传递的参数不一样,那进行函数内部的循环对象也自然不一样,你也可以自己写for循环再进行遍历但是实现起来很麻烦,因为你再次循环数据不一样你需要不同的变量命名还需要把数据传递出去
2.2引入lodash插件
<script src="../lodash.min.js"></script><script>const obj={uname:'111',age:18,hobby:['哈哈','呵呵']user:{ baby:'内部'}}const os=_.cloneDeep(obj)</script>
2.3JSON.stringify()
最简单的方法也最常用
<script>const obj={uname:'111',age:18,hobby:['哈哈','呵呵']user:{ baby:'内部'}}//先把对象转化为JSON字符串再转化为对象const os=JSON.parse(JSON.stringify(obj))</script>
总结
代码千千万,适合自己最重要。欢迎大家指出不足和问题。