JavaScript:解构赋值中的剩余元素会创建新数组吗?
问题
使用剩余元素(对象或数组)的数组解构语法,是否会在内存中创建新数组供嵌套剩余元素的解构赋值使用?比如像let [a, b, ...[c, d]] = [1, 2, 3, 4];这样的写法,初始化a和b之后,会不会创建新数组来给...[c, d]做解构操作?
之所以有这个疑问,是因为MDN在解构赋值页面的“将绑定模式用作剩余属性”部分提到:
数组解构赋值的剩余属性可以是另一个数组或对象绑定模式。内部解构会从收集剩余元素后创建的数组中进行解构,因此无法通过这种方式访问原始可迭代对象上的任何属性。
这段描述看起来明确表示会创建全新数组,而我的核心关注点是性能——创建新数组可能影响性能,想知道有没有其他实现或规范方式?另外通过性能测试发现,这种解构语法比直接let [a, b, c, d] = [1, 2, 3, 4];慢90%以上。
回答
结论:确实会创建新数组
根据ECMAScript规范和MDN的说明,这种嵌套剩余解构的执行逻辑分为两步:
- 先从原始数组中收集剩余元素,创建一个全新的数组实例存储这些值;
- 再针对这个新数组执行内层的解构赋值(即
[c, d]的解构操作)。
这也解释了MDN提到的“无法访问原始可迭代对象属性”——内层解构的目标是新数组,和原始对象没有关联。
性能差异的核心原因
你测试到的90%性能差距是合理的:
- 直接解构
let [a, b, c, d] = arr;是直接从原始数组读取对应索引的值,没有额外的内存分配和垃圾回收开销; - 嵌套剩余解构多了新数组的创建、初始化和后续销毁流程,在高频执行场景下,这类开销会被显著放大。
性能优化的替代方案
如果追求性能,最直接的方式是避免使用嵌套剩余解构,可以选择以下两种方式:
- 直接解构:
let [a, b, c, d] = arr;(性能最优) - 手动按索引取值:
let a = arr[0], b = arr[1], c = arr[2], d = arr[3];(性能和直接解构接近)
如果业务逻辑需要处理剩余元素,建议先将剩余元素赋值给变量再解构,比如:
let [a, b, ...rest] = arr; let [c, d] = rest;
这种写法和嵌套解构本质逻辑一致(仍会创建rest数组),但可读性更强,性能差异可以忽略。
内容的提问来源于stack exchange,提问作者mishar
相关产品推荐
相关产品推荐

