js -深浅拷贝
区别:
(1)深拷贝(深度克隆)
特点:拷贝的时候会生成一份新的数据,修改拷贝以后的数据不会原数据。
(2)浅拷贝(对象,数组)
特点:拷贝的时候只是拷贝了一份引用,修改拷贝以后的数据会影响原来的数据。
浅拷贝:
创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。
方式一:
直接等号赋值
let obj1 = { name:'小王', obj:{ age:20 } } let obj1Copy = obj1 obj1Copy.name = '小李'; obj1Copy.obj.age = 22; console.log(obj1) //{ name: '小李', obj: { age: 22 } } console.log(obj1Copy === obj1) //true
方式二:
使用Object.assign() 如果对象的value全是基本类型的话,也可以用Object.assign来实现深拷贝,但是要把它赋值给一个空对象
let obj1 = { name:'小王', obj:{ age:20 } } let obj1Copy ={} Object.assign(obj1Copy,obj1); obj1Copy.name = '小李'; obj1Copy.obj.age = 22; console.log(obj1) //{ name: '小王', obj: { age: 22 } } 原数据的obj.age变了,浅拷贝 console.log(obj1Copy === obj1) //false
方式三:
for···in循环(只循环第一层)
let obj1 = { name:'小王', obj:{ age:20 } } function simpleCopy(obj1) { let obj2 = Array.isArray(obj1) ? [] : {}; for (let i in obj1) { obj2[i] = obj1[i]; } return obj2; } let obj1Copy = simpleCopy(obj1) obj1Copy.name = '小李'; obj1Copy.obj.age = 22; console.log(obj1) //{ name: '小王', obj: { age: 22 } } console.log(obj1Copy === obj1) //false
深拷贝:
创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。
方式一:
通过JSON对象来实现深拷贝
缺点:
- 会忽略`undefined`
- 会忽略`symbol`
- 会忽略函数
- 不能解决循环引用的对象
let obj1 = { sex:undefined, name:'小王', obj:{ age:20 }, fn:()=>{} } let obj1Copy = JSON.parse(JSON.stringify(obj1)) obj1Copy.name = '小李'; obj1Copy.obj.age = 22; console.log(obj1) //{ sex:undefined,name: '小王', obj: { age: 20 },fn:()=>{} } console.log(obj1Copy) //{ name: '小李', obj: { age: 22 } }
方式二:
递归拷贝所有层级属性
hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中(非继承属性)是否具有指定的属性,如果 object 具有带指定名称的属性,则 hasOwnProperty 方法返回 true,否则返回 false。此方法不会检查对象原型链中的属性;该属性必须是对象本身的一个成员。
let obj1 = { sex:undefined, name:'小王', obj:{ age:20 }, fn:()=>{} } let deepClone = function (obj1) { let obj2 = Array.isArray(obj1)?[]:{} if(obj1 && typeof obj1 === 'object'){ for(key in obj1){ if(obj1.hasOwnProperty(key)){ //判断ojb子元素是否为对象,如果是,递归复制 if(obj1[key] && typeof obj1[key] ==='object'){ obj2[key] = deepClone(obj1[key]) }else{ //如果不是,简单复制 obj2[key] = obj1[key] } } } } return obj2 } let obj1Copy = deepClone(obj1); obj1Copy.sex = '男'; obj1Copy.obj.age = 22; console.log(obj1) //{sex: undefined, name: "小王", obj: {age:20}, fn: ƒ} console.log(obj1Copy) //{sex: 男, name: "小王", obj: {age:22}, fn: ƒ}