深拷贝
JSON转换
1 | const arr = [1, 2, 3, 4, 5]; |
使用JSON.parse(JSON.stringify(arr))
的方式进行深拷贝时,并不会拷贝函数。
JSON.stringify()
方法会忽略JavaScript对象中的函数成员,并将其转换为空值。
因此,在使用JSON.parse(JSON.stringify(arr))
时,任何函数成员都将丢失并转换为undefined
。
使用 JSON.parse(JSON.stringify(arr))
进行深拷贝的方式相对简单且易于理解,适合用于处理普通的数据结构。
然而,它无法正确地处理一些特殊类型的数据,例如函数、正则表达式、日期对象等,因为这些类型在 JSON 格式中无法正确表示。
MessageChannel
使用MessageChannel实现深拷贝。
MessageChannel除了用作通信还有一些hack的用法,比如用它来做deepClone。
1 | function deepClone(target) { |
使用
1 | const obj = { |
这个方法比较优秀的地方在于undefined的不会丢失,循环引用的对象也不会报错,循环点会被置为undefined,不过不能复制函数。
使用 MessageChannel
实现异步深拷贝,可以正确地处理任何类型的数据,包括特殊类型。
由于它是异步的方式,所以性能可能会受到一定影响,特别是在处理大型数据结构时会更明显。
自定义方法
1 | function deepClone(obj) { |
使用
1 | const obj = { a: 1, b: { c: 2 }, d: [3, 4],getValue(){ |
这种方式会拷贝方法。
浅拷贝
方式1
使用展开运算符可以轻松地复制
1 | const arr = [1, 2, 3, 4, 5]; |
方式2
使用数组的slice方法复制数组
1 | const arr = [1, 2, 3, 4, 5]; |
slice()
是数组对象的一个方法,用于从数组中提取指定位置的元素创建一个新的数组。
slice()
方法不会修改原始数组,而是返回一个浅拷贝(shallow copy)的新数组。
slice()
方法可以接收两个参数,即 start
和 end
。起始位置 start
是要提取的起始索引(包含在提取范围内),结束位置 end
是要提取的结束索引(不包含在提取范围内)。
如果省略 end
参数,默认会提取到数组的末尾。