var arr = new Array(4).fill({});
arr[2].status = true;
console.log(arr[0].status);
为什么数组填充在所有索引中填充相同的对象?
var arr = new Array(4).fill({});
arr[2].status = true;
console.log(arr[0].status);
为什么数组填充在所有索引中填充相同的对象?
.fill
将在数组的每个段上插入完全相同的对象(相同的实例)。
这就是为什么这样做.fill(Math.random)
会返回一个始终填充相同数字的数组。
你可以这样做来获得你想要的:
new Array(4).fill().map(() => ({}));
为了解释问题代码中发生的事情,让我们将其转换为 ES5 代码:
var arr = new Array(4); // new Array(4)
var obj = new Object(); // *1: with this object instance
for(i = 0; i < 4; i++) { // .fill( *1 )
arr[i] = obj;
}
如您所见,我们将相同的对象实例 ( obj
)分配给数组实例的每个单元格。
这是相同的原理:
const obj = {};
const a = obj;
const b = obj;
a.foo = true;
下定a.foo === b.foo
决心true
。
fill
重复传递给它的值。这种情况下的值是一个对象引用。该引用的每个副本都指向同一个对象,因此您得到的是:
+−−−−−−−−−−−+ arr--->| (数组) | +−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−+ | 0 |−−+−+−+−>| (对象) | | 1 |−/ / / +−−−−−−−−−−−−−−−+ | 2 |--/ / | 状态:真实 | | 3 |−−−/ +−−−−−−−−−−−−−−−+ +−−−−−−−−−−−+
如果需要单独的对象,则需要创建多个对象。最简单的方法当然是:
var arr = [{}, {}, {}, {}];
例子:
var arr = [{}, {}, {}, {}];
arr[2].status = true;
console.log("arr[0].status", arr[0].status);
console.log("arr[2].status", arr[2].status);
如果你想用可变长度来做:
由于您使用的是Array.fill
,我假设您使用的是 ES2015(又名“ES6”)功能(但请参阅下文了解不带 polyfill 的 ES5 兼容解决方案)。你可以通过Array.from
回调来做到这一点:
const arr = Array.from({length:4}, () => ({}));
arr[2].status = true;
console.log("arr[0].status", arr[0].status);
console.log("arr[2].status", arr[2].status);
这给了你:
+−−−−−−−−−−−+ arr--->| (数组) | +−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−+ | 0 |−−−−−−−−−>| (对象) | | 1 |−−−−−+ +−−−−−−−−−−−−−−−+ | 2 |−−−+ | | 3 |-+ | | +−−−−−−−−−−−−−−−−+ +−−−−−−−−−−+ | | +−−>| (对象) | | | +−−−−−−−−−−−−−−−−+ | | | | +−−−−−−−−−−−−−−−−+ | +−−−−->| (对象) | | +−−−−−−−−−−−−−−−−+ | | 状态:真实 | | +−−−−−−−−−−−−−−−−+ | | +−−−−−−−−−−−−−−−−+ +−−−−−−−>| (对象) | +−−−−−−−−−−−−−−−−+
(Array.from
如果你愿意,你可以在 ES5 上使用 polyfill来做到这一点,只需使用function() { return {}; }
代替() => ({})
。)
在 ES5 中,如果你需要一个可变长度,最简单的可能就是一个循环:
var arr = [];
for (var i = 0; i < 4; ++i) {
arr[i] = {};
}
arr[2].status = true;
console.log("arr[0].status", arr[0].status);
console.log("arr[2].status", arr[2].status);
当然,你可以把它放在一个辅助函数中。