我正在使用Array.fill预填充其他数组的数组。修改一个索引的数组也会修改另一个索引的数组。这意味着它是同一个对象。Array.fill为所有索引使用相同的对象
const arr = Array(2).fill([]);
arr[0].push('a');
arr[1].push('b');
// [['a', 'b'], ['a', 'b']]
我一直在阅读一些文档,但我没有看到这种行为在任何地方提及。同样的事情发生在对象文字上。
这是否有意义?
我正在使用Array.fill预填充其他数组的数组。修改一个索引的数组也会修改另一个索引的数组。这意味着它是同一个对象。Array.fill为所有索引使用相同的对象
const arr = Array(2).fill([]);
arr[0].push('a');
arr[1].push('b');
// [['a', 'b'], ['a', 'b']]
我一直在阅读一些文档,但我没有看到这种行为在任何地方提及。同样的事情发生在对象文字上。
这是否有意义?
是的。
您正在传递对创建的对象实例的引用。 如果你首先声明数组(例如,var c = []
),然后用它填充arr
,你会得到相同的行为。
const c = [];
const arr = Array(2).fill(c);
c.push("a");
c.push("b");
// c ["a", "b"]
// arr [reference to c, reference to c] => [["a","b"], ["a", "b"]]
非常感谢您的验证。我想到了发生了什么,但不知道这是否是正确的行为。 – Geuis
是的,它确实有道理。
fill
需要一个放在所有索引中的值,而不是为每个索引产生一个新值的函数。并且它不会隐式地克隆你传递的值(没有标准函数会这样做)。这只是通常的分配行为,其中对象(参考值)保持不变。
这并不回答你的问题,但如果你是在解决这个意想不到的行为,你可以使用Array.from({length:2},()=> []);预先填充阵列。 https://jsfiddle.net/qf8z69ma/ –
@JoseHermosillaRodrigo是的,这是我结束了同样的答案。 – Geuis