一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

JavaScript 中数组创建时引用类型初始化存在的逻辑隐患

时间:2026-07-01 11:22:57 编辑:袖梨 来源:一聚教程网

JavaScript中数组引用类型初始化最核心的问题是多个数组项意外共享同一份内存地址,因fill()仅复制引用而非创建新实例,导致修改一处即同步影响其余所有项。

JavaScript 中数组创建时,引用类型初始化最核心的问题是:**多个数组项意外共享同一份内存地址**。这不是语法错误,而是引用语义与初始化方式叠加导致的隐性状态污染。

为什么 new Array(n).fill([]) 会出事

这行代码看似在创建 n 个空数组,实际只生成了一个 [] 实例,然后把它的引用复制了 n 次:

  • const mat = new Array(3).fill([]);
  • 等价于:const shared = []; const mat = [shared, shared, shared];
  • 修改 mat[0].push(1)mat[1]mat[2] 也会看到 1

forEach 或 map 中复用对象引发“全变一样”

在遍历中反复赋值同一个对象,最后数组里全是它的引用副本:

  • 错误写法:let item = {}; arr.forEach((v, i) => { item.id = i; result.push(item); });
  • 结果:result 所有元素的 id 都等于最后一个 i
  • 本质:没在每次迭代中新建对象,只是不断改写同一块内存

原型上挂数组/对象,子实例集体中招

把引用类型直接写在构造函数的 prototype 上,所有实例都会共用它:

立即学习“Java免费学习笔记(深入)”;

  • Animal.prototype.tags = [];
  • const dog = new Animal(); const cat = new Animal();
  • dog.tags.push('fluffy');cat.tags 也包含 'fluffy'
  • 修复方式:在构造函数内初始化 this.tags = [],或用 get tags() { return []; }

安全初始化的三类可靠做法

关键原则:确保每个数组项、每个对象、每层嵌套都拥有独立内存实例。

  • Array.from + 回调Array.from({ length: 4 }, () => []) —— 每次回调新建子数组
  • fill().map()new Array(4).fill().map(() => []) —— 先占位再映射,避免引用复用
  • 循环手动创建const arr = []; for (let i = 0; i < 4; i++) arr[i] = []; —— 最直白可控

热门栏目