array.from 对类数组对象执行浅拷贝,即基本类型值被复制,引用类型值共享内存地址;类数组对象需有 length 属性和数字键;遍历索引“原样”赋值,不递归处理嵌套结构。

Array.from 在转换类数组时执行的是浅拷贝,不是深拷贝。它创建一个新数组,但对原始类数组中每个元素的引用关系不做递归处理——基本类型值被复制,引用类型值仍共享同一内存地址。
什么是类数组对象
类数组对象是具有 length 属性 和以数字为键的属性(如 0、1)的对象,但它没有数组原型上的方法(比如 map、push)。常见例子包括:
-
arguments对象(函数内部) -
document.querySelectorAll('div')返回的NodeList - 手动构造的对象:
{0: 'a', 1: 'b', length: 2}
Array.from 如何做浅拷贝
它遍历类数组的索引位置(从 0 到 length - 1),把每个索引对应的值“原样”放入新数组。这个过程不检查值是否为对象,也不递归复制嵌套结构。
- 如果某项是字符串、数字、布尔值等基本类型,新数组中存的是独立副本,互不影响
- 如果某项是对象、数组、函数等引用类型,新数组只保存该引用的拷贝(即指向同一块堆内存)
- 因此修改新数组中某个对象的属性,原类数组对应项也会变化
典型验证示例
看这个例子:
const arrayLike = {
0: { name: 'Alice' },
1: [1, 2],
length: 2
};
<p>const arr = Array.from(arrayLike);
arr[0].name = 'Bob';
arr[1].push(3);</p><p>console.log(arrayLike[0].name); // 'Bob' —— 原对象被改了
console.log(arrayLike[1]); // [1, 2, 3] —— 原数组也被改了</p>这说明 Array.from 并未隔离引用类型的深层结构,完全符合浅拷贝定义。
和 mapFn 结合时要注意
当传入第二个参数(映射函数)时,Array.from 会在拷贝后立即对每一项调用该函数,但仍不改变浅拷贝本质:
-
Array.from(obj, x => ({...x}))可以实现一层解构,但仅限顶层对象 -
Array.from(obj, JSON.parse(JSON.stringify(x)))不推荐(会丢函数、undefined、Date 等) - 真正需要深拷贝嵌套结构时,应单独使用
structuredClone或第三方库
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











