扩展运算符(Spreading)是否创建浅拷贝?结合代码实例辨析
扩展运算符(Spreading)是否会创建浅拷贝?
简单说:扩展运算符实现的是浅拷贝,不是深拷贝——你看到的「三个数组各自拥有独立副本」的现象,只是因为你的代码里数组元素都是基本类型(number)而已。
先来看你的代码运行后的实际输出,我们先把代码贴出来:
let first:number[] = [1, 2]; let second:number[] = [3, 4]; let both_plus:number[] = [0, ...first, ...second, 5]; console.log(`both_plus is ${both_plus}`); first[0] = 20; console.log(`first is ${first}`); console.log(`both_plus is ${both_plus}`); both_plus[1]=30; console.log(`first is ${first}`); console.log(`both_plus is ${both_plus}`);
运行后输出会是:
both_plus is 0,1,2,3,4,5 first is 20,2 both_plus is 0,1,2,3,4,5 first is 20,2 both_plus is 0,30,2,3,4,5
为什么会出现「修改原数组不影响拷贝后的数组」的情况?因为数组里的元素是基本类型(number),基本类型的值是直接存储在栈内存中的,扩展运算符拷贝的时候会直接复制这些值,所以修改原数组的基本类型元素,只会改变原数组里的那个值,不会影响拷贝出来的独立值——这是浅拷贝在处理基本类型时的表现,不是深拷贝的特征。
那什么是浅拷贝的本质?如果数组里的元素是引用类型(比如对象、嵌套数组),扩展运算符只会复制引用,而不是整个引用类型的内部结构。举个例子:
let first = [{a: 1}, 2]; let both_plus = [0, ...first]; first[0].a = 20; // 修改原数组中对象的属性 console.log(both_plus[0].a); // 输出 20,说明拷贝的是引用
这时候就能看出来,扩展运算符并没有深拷贝引用类型的元素,只是复制了它们的引用,原数组和拷贝后的数组共享同一个引用类型的对象——这才是浅拷贝的核心表现。
所以回到你的问题:扩展运算符不会创建深拷贝,它做的是浅拷贝,你代码里的「独立副本」只是基本类型拷贝后的特殊情况而已。
内容的提问来源于stack exchange,提问作者overexchange
相关产品推荐
相关产品推荐

