跳到主要内容

深拷贝与浅拷贝

浅拷贝

展开语法...

const tempObj = { id: 1, name: '江山录' }
const copyObj = { ...tempObj }

Array.prototype.concat()

链接两个数组。

const array1 = ['a', 'b', 'c']
const array2 = ['d', 'e', 'f']
const array3 = array1.concat(array2)
console.log(array3)
// output: Array ["a", "b", "c", "d", "e", "f"]

Array.prototype.slice()

提起数组中的内容,组成新数组。

  • slice() 方法返回一个新的数组对象,这一对象是一个由 startend 决定的原数组的浅拷贝(包括 start ,不包括 end ),
  • 其中 startend 代表了数组元素的索引。
  • 原始数组不会被改变。
const animals = ['ant', 'bison', 'camel', 'duck', 'elephant']
console.log(animals.slice(2))
// output: Array ["camel", "duck", "elephant"]
console.log(animals.slice(2, 4))
// output: Array ["camel", "duck"]
console.log(animals.slice(1, 5))
// output: Array ["bison", "camel", "duck", "elephant"]
console.log(animals.slice(-2))
// output: Array ["duck", "elephant"]
console.log(animals.slice(2, -1))
// output: Array ["camel", "duck"]
console.log(animals.slice()) // 浅拷贝一份数组
// output: Array ["ant", "bison", "camel", "duck", "elephant"]

Array.from()

分解组合成新对象

  • Array.from() 静态方法从可迭代或类数组对象创建一个新的浅拷贝的数组实例。
  • 转换异步的可迭代对象到数组,可以使用 Array.fromAsync()
console.log(Array.from('foo'))
// output: Array ["f", "o", "o"]
console.log(Array.from([1, 2, 3], (x) => x + x))
// output: Array [2, 4, 6]

Object.assign()

后对象覆盖前对象相同属性的内容,组成一个新对象

  • assign 译: 分派,布置(工作、任务等);
  • Object.assign() 静态方法将一个或者多个源对象中所有可枚举的自有属性复制到目标对象,并返回修改后的目标对象。
const target = { a: 1, b: 2 }
const source = { b: 4, c: 5 }
const returnedTarget = Object.assign(target, source)
console.log(target)
// output: Object { a: 1, b: 4, c: 5 }
console.log(returnedTarget === target)
// output: true

Object.create()

以一个旧对象为原型创建一个新对象。

  • Object.create() 静态方法以一个现有对象作为原型,创建一个新对象。
const person = {
isHuman: false,
printIntroduction: function () {
console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`)
},
}
const me = Object.create(person)
me.name = 'Matthew' // "name" is a property set on "me", but not on "person"
me.isHuman = true // Inherited properties can be overwritten
me.printIntroduction()
// output: "My name is Matthew. Am I human? true"

深拷贝

JSON.parse(JSON.stringify(xxx))

  • 如果一个 JavaScript 对象可以被序列化,则存在一种创建深拷贝的方式:
  • 使用 JSON.stringify() 将该对象转换为 JSON 字符串,然后使用 JSON.parse() 将该字符串转换回(全新的) JavaScript 对象:
let ingredients_list = ['noodles', { list: ['eggs', 'flour', 'water'] }]
let ingredients_list_deepcopy = JSON.parse(JSON.stringify(ingredients_list))

// Change the value of the 'list' property in ingredients_list_deepcopy.
ingredients_list_deepcopy[1].list = ['rice flour', 'water']
// The 'list' property does not change in ingredients_list.
console.log(ingredients_list[1].list)
// Array(3) [ "eggs", "flour", "water" ]

structuredClone()

  • 全局的 structuredClone() 方法使用结构化克隆算法将给定的值进行深拷贝。
  • 该方法还支持把原始值中的可转移对象转移到新对象,而不是把属性引用拷贝过去。
  • 可转移对象与原始对象分离并附加到新对象;它们不可以在原始对象中访问被访问到。
// Create an object with a value and a circular reference to itself.
const original = { name: 'MDN' }
original.itself = original

// Clone it
const clone = structuredClone(original)
console.assert(clone !== original) // the objects are not the same (not same identity)
console.assert(clone.name === 'MDN') // they do have the same values
console.assert(clone.itself === clone) // and the circular reference is preserved