数组和对象的拷贝(复制)

目录

浅拷贝(shallow copy)

浅拷贝方法

数组浅拷贝方法一:.slice()

数组浅拷贝方法二:...展开运算符

对象浅拷贝方法一:Object.assign(目标对象, 被复制的对象)

对象浅拷贝方法二:...展开运算符

深拷贝(deep copy)

深拷贝方法

方法一:structuredClone()    浏览器提供

方法二:JSON

缺陷(面试题)

手动实现深拷贝和浅拷贝


复制必须要产生新的对象。以下代码不是复制。

const arr = ["孙悟空", "猪八戒", "沙和尚"]

const arr2 = arr  // 不是复制,只是将arr的值赋给arr2,他们指的还是一个对象

console.log(arr)    // 二者输出一样
console.log(arr2)

代码在内存中的表现:

如何判断是不是复制了一个对象:看复制以后修改新对象的值,旧对象是否发生变化,不变则是复制,改变则不是复制(因为两个对象都指向同一个对象)

console.log(arr === arr2)
// true  =》 不是复制
// false =》 是复制

浅拷贝(shallow copy)

通常对对象的拷贝都是浅拷贝。浅拷贝顾名思义,只对对象的浅层进行复制(只复制一层)。如果对象中存储的数据是原始值,那么拷贝的深浅是不重要。浅拷贝只会对对象本身进行复制,不会复制对象中的属性(或元素)。

浅拷贝在内存中的表现:

对象不一样,但是里面的元素是一样的

 

浅拷贝方法

数组浅拷贝方法一:.slice()

不需要任何参数。当调用slice时,会产生一个新的数组对象,从而完成对数组的复制

const arr = ["孙悟空", "猪八戒", "沙和尚"]


const arr3 = arr.slice()

console.log(arr === arr3)   // false


arr3[0] = "唐僧"

console.log(arr)   // ["孙悟空", "猪八戒", "沙和尚"]

console.log(arr3)  // ["唐僧", "猪八戒", "沙和尚"]

 复制在内存中的表现:

数组浅拷贝方法二:...展开运算符

可以将一个数组中的元素展开到另一个数组中或者作为函数的参数传递,表示将数组中的元素放到新数组中

const arr = ["孙悟空", "猪八戒", "沙和尚"]

const arr3 = [...arr]   //  等同于const arr3 = [arr[0], arr[1], arr[2]]

const arr3 = ["唐僧", ...arr, "白骨精"]
console.log(arr)   // ["孙悟空", "猪八戒", "沙和尚"]
console.log(arr3)  // ["唐僧", "孙悟空", "猪八戒", "沙和尚", "白骨精"]

<补充>...用法

function sum(a, b, c) {
    return a + b + c
}

const arr4 = [10, 20, 30]

let result = sum(...arr4)  // 等同于let result = sum(arr4[0], arr4[1], arr4[2])

console.log(result)  // 60

对象浅拷贝方法一:Object.assign(目标对象, 被复制的对象)

将被复制对象中的属性复制到目标对象里,并将目标对象返回

const obj = { name: "孙悟空", age: 18 }

const obj2 = Object.assign({}, obj)

console.log(obj2)   //  { name: "孙悟空", age: 18 }

第一个参数的属性值会被第二个参数的覆盖:

const obj = { name: "孙悟空", age: 18 }

const obj2 = Object.assign({}, obj)

const obj2 = { address: "花果山"}  // obj2新增属性
console.log(obj2)  //  { name: "孙悟空", age: 18, address: "花果山" }


const obj2 = { address: "花果山", age: 28 }
Object.assign(obj2, obj)
console.log(obj2)   //  { name: "孙悟空", age: 18, address: "花果山" }

对象浅拷贝方法二:...展开运算符

const obj = { name: "孙悟空", age: 18 }

const obj3 = { address: "高老庄", ...obj, age: 48 } // obj3在后,obj3数据覆盖obj4的数据
console.log(obj3)   // { name: "孙悟空", age: 48, address: "高老庄" }


const obj3 = { address: "高老庄", age: 48, ...obj } // obj在后,obj数据覆盖obj3的数据
console.log(obj3)   // { name: "孙悟空", age: 18, address: "高老庄" }

深拷贝(deep copy)

深拷贝指不仅复制对象本身,还复制对象中的属性和元素。因为性能问题,通常情况不太使用深拷贝。

深拷贝在内存中的表现:

深拷贝方法

方法一:structuredClone()    浏览器提供

const arr = [{name:"孙悟空"}, {name:"猪八戒"}]

const arr3 = structuredClone(arr) // 浏览器提供的专门用来深拷贝的方法

console.log(arr)
console.log(arr3)

方法二:JSON

const obj = {
     name: "孙悟空",
     age: 18,
}

const obj2 = JSON.parse(JSON.stringify(obj)) 

缺陷(面试题)

  • NaN          ===》null
  • undefined ===》 空
  • 时间戳      ===》字符串时间
  • 错误信息  ===》 空对象
  • Infinity      ===》null

手动实现深拷贝和浅拷贝

见=》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值