JavaScript中数组直接赋值、slice()与扩展运算符的区别及深浅拷贝关联
JavaScript数组直接赋值、slice()与扩展运算符的区别解析
先看示例代码:
const a = [1,2,3,4,5]; const b = a; const c = a.slice(); const d = [...a];
变量b:和原数组共享同一引用
const b = a; 这一步不是拷贝,只是把数组a的内存引用地址赋值给了b。换句话说,b和a是同一个数组的两个“别名”——不管修改哪一个的内容,另一个都会同步变化:
b.push(6); console.log(a); // 输出 [1,2,3,4,5,6],a和b指向同一个数组
变量c和d:都是原数组的浅拷贝
a.slice()(不带参数时)和[...a]的效果完全一致:创建一个全新的数组实例,把原数组a的第一层元素挨个复制到新数组里。所以c和d都是独立于a的新数组,修改它们不会影响原数组:
c.push(6); console.log(a); // 输出 [1,2,3,4,5],不受c的修改影响 d.pop(); console.log(a); // 依然是 [1,2,3,4,5],和d的操作无关
但要注意:这两种方法都是浅拷贝——如果原数组包含引用类型(比如对象、嵌套数组),新数组只会复制这些元素的引用地址,而非重新创建新的对象/数组。比如:
const a = [{name: 'Alice'}, 2, 3]; const c = a.slice(); const d = [...a]; // 修改c里的对象属性 c[0].name = 'Bob'; console.log(a[0].name); // 输出 'Bob',a和c的第一个元素指向同一个对象 console.log(d[0].name); // 同样输出 'Bob',d的引用也指向同一个对象
和浅拷贝、深拷贝的关系
- 直接赋值(
b的情况):不属于任何拷贝,只是引用传递,两个变量共享同一个数组。 - slice()和扩展运算符(
c、d的情况):属于浅拷贝,仅能复制数组的第一层元素;遇到嵌套的引用类型时,无法实现完全独立的复制。 - 深拷贝:需要递归复制所有层级的引用类型(比如用
JSON.parse(JSON.stringify(a))或手写递归函数),这样新数组和原数组的所有嵌套元素都完全独立,互不影响。
内容的提问来源于stack exchange,提问作者coolest-duck
相关产品推荐
相关产品推荐

