什么是浅拷贝?
误区:浅拷贝不等于赋值!!
浅拷贝的概念:循环对象,把对象中最外层的属性拷贝出来,给到一个新对象。如果最外层的属性中有复杂数据类型,那么拷贝的就是内存地址。
实现浅拷贝有三种方式:
第一种代码示例:
<script>
let obj = {
id:1,
name:"孙悟空",
age:14,
info:{
address:"花果山"
}
}
let o1 = {};
// obj 就是要浅拷贝的对象
for(let k in obj){
// k是属性名 obj[k]是属性值
o1[k] = obj[k];
}
// 此时是浅拷贝,o1里的info和obj里的info指向的是同一个内存地址
o1.info.address = "天宫"; // 修改了o1里的address,obj里的address也会被修改
console.log(obj.info.address); // 天宫
</script>
第二种代码示例(最简单也最常用):
<script>
let obj = {
id:1,
name:"孙悟空",
age:14,
info:{
address:"花果山"
}
}
// 使用点语法也可以实现浅拷贝
let o1 = {...obj};
console.log(o1)
</script>
ES6中新增了一个浅拷贝的方法:Object.assign(target,sources);
assign单词的意思是分配
参数:target 要拷贝给哪个对象,也就是o1,sources 被拷贝的对象,也就是obj
第三种代码示例:
<script>
let obj = {
id:1,
name:"孙悟空",
age:14,
info:{
address:"花果山"
}
}
let o1 = {};
for(let k in obj){
// k是属性名 obj[k]是属性值
o1[k] = obj[k];
}
// 同样也是浅拷贝
// 把obj对象的数据浅拷贝给新对象o1
Object.assign(o1,obj);
console.log(o1);
</script>
什么是深拷贝?
深拷贝的概念:把对象身上的每一层属性都进行拷贝,赋值给一个新对象
深拷贝有两种方式:
1.JSON序列化
<script>
let obj = {
id:1,
name:"孙悟空",
age:14,
info:{
address:"花果山"
}
}
let jsonStr = JSON.stringify(obj)
let o1 = JSON.parse(jsonStr)
console.log(o1)
</script>
但JSON序列化有缺点
1)如果要拷贝的对象中数据很复杂,而且很多,那么转换的性能很低
2)不能被JSON识别的数据,不会被拷贝到新的对象中
2.自己写递归
<script>
let obj = {
id:1,
name:"孙悟空",
age:14,
info:{
address:"花果山"
}
}
// 深拷贝obj对象中的数据到o1中
// 参数obj表示的是要深拷贝的对象
function deepClone(obj){
// 判断是否需要进行深拷贝,如果是简单类型不需要,复杂类型则需要
if(typeof obj !== 'object') return obj
// 判断传递的obj是否是数组,如果是返回数组类型,否则返回对象类型
let o1 = Array.isArray(obj) ? [] : {}
for(let k in obj){
// 只拷贝对象本身的属性,不拷贝原型身上的属性
if(obj.hasOwnProperty(k)){
o1[k] = deepClone(obj[k])
}
}
return o1
}
let o1 = deepClone(obj)
o1.info.address = '天宫'
console.log(obj.info.address) // 还是花果山,没有被修改
</script>
本文详细介绍了JavaScript中的浅拷贝和深拷贝概念,通过实例展示了浅拷贝的三种实现方式,包括手动复制、扩展运算符和`Object.assign()`。同时,深入探讨了深拷贝的两种实现方法:JSON序列化及其局限性,以及递归实现深拷贝。文章强调了浅拷贝只复制最外层属性,而深拷贝会复制所有层级的属性,确保新对象与原对象相互独立。
2037

被折叠的 条评论
为什么被折叠?



