通过案列理解js中的深拷贝和浅拷贝
浅拷贝:浅拷贝会创建一个新对象或数组,新对象或数组会复制原始对象或数组的一层属性。对于基本数据类型的属性,会直接复制其值;而对于引用数据类型的属性,只会复制其引用,即新对象和原始对象中的引用数据类型属性会指向同一个内存地址。
…扩展运算符是浅拷贝
// 浅拷贝示例
const originalObj = {name: 'John',age: 30,hobbies: ['周杰伦', '邓紫棋']
};// 使用扩展运算符进行浅拷贝
const shallowCopy = {...originalObj };// 修改浅拷贝对象的基本数据类型属性
shallowCopy.name = 'Jane';
// 修改浅拷贝对象的引用数据类型属性
shallowCopy.hobbies.push('赵四');console.log(originalObj.name); // 输出: John //基本数据类型的属性,会直接复制源对象的值
console.log(originalObj.hobbies); // 输出: ['周杰伦', '邓紫棋', '赵四'] // 复制其引用
object.assign也是浅拷贝
Object.assign()方法接收的第一个参数作为目标对象,后面的所有参数作为源对象
let outObj = {inObj: {a: 1, b: 2}
}
let newObj = Object.assign({}, outObj)
newObj.inObj.a = 2
console.log(outObj) // {inObj: {a: 2, b: 2}}
数组方法的浅拷贝 map(), filter() , reduce()
map()浅拷贝
const original = [1, { name: 'Alice' }, [3, 4]];// 使用 map 创建新数组
const copyMap = original.map(item => item);console.log(copyMap); // [1, { name: 'Alice' }, [3, 4]]
console.log(copyMap === original); // false (新数组)
console.log(copyMap[1] === original[1]); // true (对象引用相同)// 修改原数组中的对象
original[1].name = 'Bob';
console.log(copyMap[1].name); // 'Bob' (同步修改)
filter() 浅拷贝
const original = [1, { name: 'Alice' }, [3, 4]];// 使用 filter 创建新数组(保留所有元素)
const copyFilter = original.filter(() => true);console.log(copyFilter); // [1, { name: 'Alice' }, [3, 4]]
console.log(copyFilter === original); // false (新数组)
console.log(copyFilter[2] === original[2]); // true (数组引用相同)
// 修改原数组中的嵌套数组
original[2].push(5);
console.log(copyFilter[2]); // [3, 4, 5] (同步修改)
reduce()浅拷贝
const original = [1, { name: 'Alice' }, [3, 4]];// 使用 reduce 构建新数组
const copyReduce = original.reduce((acc, item) => {acc.push(item);return acc;
}, []);console.log(copyReduce); // [1, { name: 'Alice' }, [3, 4]]
console.log(copyReduce === original); // false (新数组)
console.log(copyReduce[0] === original[0]); // true (值相同)
console.log(copyReduce[1] === original[1]); // true (对象引用相同)// 添加新元素到原始数组
original.push(5);
console.log(original.length); // 4
console.log(copyReduce.length); // 3 (不共享长度变化)
深拷贝:深拷贝就是完完全全拷贝一份新的对象,它会在内存的堆区域重新开辟空间,修改拷贝对象就不会影响到源对象
数组深拷贝方法:concat(), slice() ,Array.from()
//数组//1.concat()(这里实现了深拷贝)const n =['你好','周杰伦']// concat方法创建并返回一个新的数组,新数组包含调用concat方法放入数组的元素const j = [].concat(n) j.push('你好','邓紫棋')console.log('n=',n) // n= (2) ["你好", "周杰伦"]console.log('j=',j) //j= (4) ["你好", "周杰伦", "你好", "邓紫棋"]//2.slice() 方法(这里实现了深拷贝)const k =['你好','周杰伦']const i = k.slice() k.push('你好','邓紫棋')console.log('k=',k) //k= Array(4)[0: "你好" 1: "周杰伦" 2: "你好" 3: "邓紫棋"]console.log('i=',i)//i= Array(2)[0: "你好" 1: "周杰伦"]//3. Array.from() 方法(这里实现了深拷贝)const n =['你好','周杰伦']const j = Array.from(n) j.push('你好','邓紫棋')console.log('n=',n) // n= Array(2)[0: "你好" 1: "周杰伦"]console.log('j=',j) // j= Array(4)[0: "你好" 1: "周杰伦" 2: "你好" 3: "邓紫棋"]