高阶JavaScript四部曲:1深浅拷贝:就如你想象的那样,完全操控JavaScript!
2023-11-17 02:45:00
浅拷贝与深拷贝:JavaScript 中的对象复制详解
在 JavaScript 开发中,对对象进行复制是常见操作,但了解不同复制方法之间的细微差别至关重要。浅拷贝和深拷贝是 JavaScript 中用来复制对象的两种基本技术,它们在复制过程和影响上有显著差异。
浅拷贝
浅拷贝 涉及复制对象属性的值,如果属性值是简单类型(例如字符串或数字),则复制实际值。但是,如果属性值是引用类型(例如数组或对象),则浅拷贝只会复制该属性的内存地址。因此,原始对象和副本指向相同的底层数据结构。
const obj1 = {
name: '张三',
age: 20,
friends: ['李四', '王五']
};
const obj2 = Object.assign({}, obj1);
console.log(obj2); // { name: '张三', age: 20, friends: ['李四', '王五'] }
obj2.name = '李四';
obj2.friends.push('赵六');
console.log(obj1); // { name: '李四', age: 20, friends: ['李四', '王五', '赵六'] }
在这个示例中,obj1
和 obj2
都是引用类型,obj2
是 obj1
的浅拷贝。当修改 obj2
的属性或属性值时,obj1
也受到影响。这是因为浅拷贝仅复制了属性的值,而没有复制对象本身。
深拷贝
深拷贝 不仅复制对象属性的值,还复制属性本身。无论属性值是简单类型还是引用类型,它都会被复制。因此,如果复制的是引用类型的值,则原始对象和副本将指向不同的底层数据结构。
const obj1 = {
name: '张三',
age: 20,
friends: ['李四', '王五']
};
const obj2 = JSON.parse(JSON.stringify(obj1));
console.log(obj2); // { name: '张三', age: 20, friends: ['李四', '王五'] }
obj2.name = '李四';
obj2.friends.push('赵六');
console.log(obj1); // { name: '张三', age: 20, friends: ['李四', '王五'] }
在这个示例中,obj2
是 obj1
的深拷贝。当修改 obj2
的属性或属性值时,obj1
不会受到影响。这是因为深拷贝复制了对象本身以及其所有属性和属性值。
浅拷贝与深拷贝的选择
浅拷贝和深拷贝各有其优缺点。
浅拷贝的优点:
- 速度快
- 占用内存少
浅拷贝的缺点:
- 不能复制引用类型的值
- 复制引用类型的值时,原始对象和副本指向同一底层数据结构
深拷贝的优点:
- 可以复制引用类型的值
- 复制引用类型的值时,原始对象和副本指向不同的底层数据结构
深拷贝的缺点:
- 速度慢
- 占用内存多
在实际开发中,选择浅拷贝还是深拷贝应根据具体情况而定。
总结
浅拷贝和深拷贝是 JavaScript 中复制对象的重要技术,它们在复制过程和影响上有不同的特性。浅拷贝只复制属性值,而深拷贝则复制整个对象。在选择哪种方法时,应考虑具体情况的需要和权衡。熟练掌握浅拷贝和深拷贝有助于编写更高效、更健壮的 JavaScript 代码。
5 个常见问题解答
-
何时使用浅拷贝?
- 当不需要复制引用类型的值时
- 当需要快速复制对象时
- 当内存使用是关键因素时
-
何时使用深拷贝?
- 当需要复制引用类型的值时
- 当需要避免修改原始对象时
- 当需要创建完全独立的对象副本时
-
如何创建浅拷贝?
- 使用
Object.assign()
方法 - 使用扩展运算符
...
- 使用
-
如何创建深拷贝?
- 使用
JSON.parse(JSON.stringify())
方法 - 使用循环和递归
- 使用
-
浅拷贝和深拷贝有什么区别?
- 浅拷贝只复制属性值,而深拷贝复制整个对象
- 浅拷贝复制引用类型的值时,原始对象和副本指向同一底层数据结构,而深拷贝创建独立副本