JavaScript中数组引用类型初始化最核心的问题是多个数组项意外共享同一份内存地址,因fill()仅复制引用而非创建新实例,导致修改一处即同步影响其余所有项。
JavaScript 中数组创建时,引用类型初始化最核心的问题是:**多个数组项意外共享同一份内存地址**。这不是语法错误,而是引用语义与初始化方式叠加导致的隐性状态污染。
这行代码看似在创建 n 个空数组,实际只生成了一个 [] 实例,然后把它的引用复制了 n 次:
const mat = new Array(3).fill([]);const shared = []; const mat = [shared, shared, shared];
mat[0].push(1),mat[1] 和 mat[2] 也会看到 1
在遍历中反复赋值同一个对象,最后数组里全是它的引用副本:
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({ length: 4 }, () => []) —— 每次回调新建子数组new Array(4).fill().map(() => []) —— 先占位再映射,避免引用复用const arr = []; for (let i = 0; i < 4; i++) arr[i] = []; —— 最直白可控