JavaScript 面试题
目录

如何实现对象的浅拷贝?请写出至少两种方法。

· 约 4 分钟读完 · 第 30 / 507 章

推荐答案

方法一:使用 Object.assign()

方法二:使用展开运算符 ...

本题详细解读

浅拷贝的概念

浅拷贝是指创建一个新的对象,这个新对象拥有原始对象属性值的精确副本。如果属性是原始类型(number, string, boolean, null, undefined, symbol),那么拷贝的是值本身。如果属性是引用类型(对象、数组),那么拷贝的是引用地址,即新对象和原始对象指向同一块内存空间。这意味着,如果修改拷贝对象中引用类型的属性,原始对象中对应的属性也会被修改,反之亦然。

方法一:Object.assign()

Object.assign() 方法用于将所有可枚举的自有属性从一个或多个源对象复制到目标对象。它会返回修改后的目标对象。

  • 原理: Object.assign() 会遍历源对象的所有可枚举属性,并将这些属性直接复制到目标对象。对于原始类型,复制的是值;对于引用类型,复制的是引用地址。
  • 特点:
    • 目标对象是第一个参数。
    • 如果目标对象有与源对象相同的属性,则源对象的属性会覆盖目标对象的属性。
    • 如果源对象是 null 或 undefined, 会被忽略。
  • 应用: 当我们想要创建一个与原对象相似的新对象,但又不希望新对象的修改影响原对象时,可以使用 Object.assign() 来创建一个浅拷贝的对象。

方法二:展开运算符 ...

展开运算符 ... 可以用于在字面量对象中展开一个对象,创建一个新的对象。

  • 原理: 展开运算符会遍历源对象的所有属性,并将这些属性拷贝到新的对象中,对于原始类型,复制的是值;对于引用类型,复制的是引用地址。
  • 特点:
    • 语法简洁,可读性强。
    • 与 Object.assign() 功能类似,都是浅拷贝。
  • 应用: 可以直接使用在字面量对象创建中,代码更加简洁。

两种方法的共同点与区别

  • 共同点:
    • 两种方法都是浅拷贝,对原始类型的属性值进行值拷贝,对引用类型的属性值进行地址拷贝。
    • 都会返回一个新的对象。
    • 都可以实现简单的对象复制。
  • 区别:
    • Object.assign() 是一个方法,可以接受多个源对象作为参数,将这些源对象的属性合并到目标对象。
    • 展开运算符 ... 是一个语法糖,只能将一个对象展开到字面量对象中。
    • 展开运算符语法更简洁。

注意事项

  • 浅拷贝无法解决嵌套对象(深层引用类型)的问题,如果需要完全隔离新对象和原对象之间的修改影响,需要进行深拷贝。
  • 在实际开发中,应该根据具体的需求选择浅拷贝还是深拷贝。如果对象嵌套层次不深,且不希望修改原对象中的深层引用类型,使用浅拷贝即可;反之,则需要使用深拷贝。