扩展运算符是不是深拷贝,深拷贝和浅拷贝总结

1.ES6中新增了扩展运算符,可以实现对数组和对象的复制,这种复制是深拷贝还是浅拷贝?

let arr = [10,20,30]
let arr0 = [...arr]
console.log(arr === arr0)  // false

arr和arr0的比较结果为false,那么我们初步判断二者不是同一个地址引用,接下来修改arr0,来观测arr是否发生改变:

arr0 = 'hello'
console.log(arr)

在这里插入图片描述

修改arr0的值,并不影响arr值的改变,是不是说明扩展运算符的复制就是深拷贝呢?
接下来,测试一下复杂的数组:

let arr = [[10], [20], [30]],
    arr0 = [...arr]
console.log(arr === arr0) // false
arr0[0][0] = 'hello'
console.log(arr)
console.log(arr0)

在这里插入图片描述

我们修改数组的第一个元素,发现两个数组的值都发生了改变,说明扩展符不是深拷贝,依然是浅拷贝

2.总结,哪些方案可以实现“浅拷贝”和“深拷贝”

浅拷贝

  • Object.assign() 该方法用于对象复制时,是浅拷贝
  • 数组的①slice()方法、②concat()方法、③Array.from()方法、④扩展运算符都算是浅拷贝
// target--->目标对象
// source--->源对象
// 返回值:target,即目标对象
Object.assign(target, ...sources)
// slice() 方法可从已有的数组中返回选定的元素。
// 语法:arrayObject.slice(start,end)
// 返回一个新的数组,包含从 start 到 end (不包括该元素)的 arrayObject 中的元素
var arr=['aa','bb','cc','dd','ee','ff'];
var data=arr.slice(2,4);
新数组data结果为: ["cc", "dd"]
// 合并三个数组的值
var hege = ["Cecilie", "Lone"];
var stale = ["Emil", "Tobias", "Linus"];
var kai = ["Robin"];
var children = hege.concat(stale,kai);

Array.from()方法就是将一个类数组对象或者可遍历对象转换成一个真正的数组

let obj = {
   '0': 'james',
    '1': 'kobe',
    'length': 2
}
let arr1 = Array.from(obj)
console.log(arr1);   // ["james", "kobe"]

// 对象的属性为其他的字符串类型
let obj = {
    'name1': 'james',
    'name2': 'kobe',
    length: 2
}
let arr2 = Array.from(obj)
console.log(arr2);   // [undefined, undefined]

// 没有length的对象
let obj = {
    '0': 'james',
    '1': 'kobe'
}
let arr = Array.from(obj)
console.log(arr);   // []

// set, map, array
let arr = [1,2,3]
let set = new Set(arr);
let arr1 = Array.from(set)
console.log(arr1);   ///[1,2,3]

深拷贝

目前能实现深拷贝的办法

  1. 递归方案(通过循环一层一层的进行拷贝)
  2. JSON.parse()方法,但有缺点,对于undefined、function、symbol 会被忽略
posted @ 2022-12-06 22:17  轻风细雨_林木木  阅读(103)  评论(0编辑  收藏  举报