Copy array by value
Copy array by value
技术背景
在 JavaScript 中,数组是引用类型,直接使用赋值操作符(=
)复制数组,实际上只是复制了数组的引用,而不是数组的值。这意味着修改新数组会影响原数组,反之亦然。因此,需要使用特定的方法来实现数组按值复制,确保新数组和原数组相互独立。
实现步骤
1. 确定数组元素类型
数组元素可分为三种类型:
- 字面量值(Literal values):如布尔值、数字、字符串。
- 字面量结构(Literal structures):如数组、对象。
- 原型对象(Prototypes):如
new Boolean()
、new Number()
等创建的对象。
2. 根据元素类型选择复制方法
2.1 仅包含字面量值的数组
可使用以下方法:
slice()
:let newArray = oldArray.slice();
- 扩展运算符(Spread operator):
let newArray = [...oldArray];
splice(0)
:let newArray = oldArray.splice(0);
concat()
:let newArray = oldArray.concat();
2.2 包含字面量值和字面量结构的数组
可使用 JSON.parse(JSON.stringify(myArray))
方法,但该方法无法处理原型对象和函数。
2.3 包含所有类型元素的数组
structuredClone()
:let newArray = structuredClone(oldArray);
- 使用第三方库,如 Lodash 的
cloneDeep()
或 jQuery 的extend(true, [], myArray)
。 - 自定义递归函数:
1 |
|
核心代码
浅拷贝示例
1 |
|
深拷贝示例
1 |
|
最佳实践
- 性能考虑:对于简单的数组复制,
for
循环性能最高,但代码较冗长;.slice()
方法性能也不错,且代码简洁,适合日常使用。避免在不需要深拷贝且对性能有要求的场景使用JSON.parse(JSON.stringify(arr))
,因为该方法有较大的开销。 - 兼容性考虑:使用
structuredClone()
方法时,需注意浏览器兼容性;Array.from()
方法在旧浏览器中支持不佳,使用前需检查支持情况。
常见问题
- 浅拷贝问题:使用
slice()
、concat()
等方法进行浅拷贝时,对于数组中的对象或嵌套数组,只是复制了引用,修改新数组中的对象或嵌套数组会影响原数组。解决方法是使用深拷贝方法。 JSON.parse(JSON.stringify())
的局限性:该方法无法处理函数、正则表达式、日期对象等特殊对象,会丢失这些对象的方法和属性。- 兼容性问题:一些新的方法和特性(如
structuredClone()
、扩展运算符)在旧浏览器中可能不支持,需考虑兼容性或使用转译工具。
Copy array by value
https://119291.xyz/posts/copy-array-by-value/