JavaScript - 为什么Array.prototype.fill实际上填充了“指针”?填充“new Object()”之类的对象 [英] JavaScript - why Array.prototype.fill actually fills a "pointer" of object when filling anything like 'new Object()'
问题描述
我试图使用Array.prototype.fill方法来创建焦虑 2D数组,但代码是错误的,我最终发现里面的所有数组实际上是指针到同一个数组。
I was trying to used Array.prototype.fill method to create a n x n 2D array but the code was buggy and I eventually found out all arrays inside are actually "pointers" to the same array.
示例:
var matrix = new Array(10).fill(new Array(10), 0);
我认为从概念上讲这可以创建一个10 x 10的2D阵列。但是,如果我将值赋给矩阵[0] [0]:
I thought conceptually this could create a 10 x 10 2D array. However if I assign value to matrix[0][0]:
matrix[0][0] = 1;
结果实际上是:
matrix[0][0] === 1;
matrix[1][0] === 1;
matrix[2][0] === 1;
matrix[3][0] === 1;
matrix[4][0] === 1;
matrix[5][0] === 1;
matrix[6][0] === 1;
matrix[7][0] === 1;
matrix[8][0] === 1;
matrix[9][0] === 1;
每次如果我试图为矩阵中的任何位置赋值,所有相应位置在其他子阵列中也会发生变化。
and every time if I tried to assign value to any of the position in the matrix, all corresponding positions in other sub-arrays will change as well.
我想知道为什么会发生这种情况?
I am wondering why it's happening?
任何人都可以请回答这个令人头疼的问题?
Can anyone please answer this head-scratching question?
推荐答案
我想知道为什么会这样?
I am wondering why it's happening?
数组#fill
获取值你给它作为第一个参数,并使用值的副本填充数组。
Array#fill
takes the value you give it as the first argument, and fills the array with copies of that value.
您给它的值是对数组的引用,所以它自然给你回来的是一个充满该参考文献副本的数组。不是数组的副本,引用的副本。
The value you're giving it is a reference to an array, so naturally what it gives you back is an array filled with copies of that reference. Not copies of the array, copies of the reference.
例如,它的行为完全相同原因此代码:
E.g., it behaves this way for exactly the same reason this code:
var a = new Array(10);
var b = a;
...给我们留下 a
和 b
都引用相同的数组(两者都包含相同的值;对我们创建的单个数组的引用)。
...leaves us with a
and b
both referring to the same array (both containing the same value; a reference to the single array we've created).
让我们抛出一些Unicode艺术:
Let's throw some Unicode-art at it:
此代码运行后:
var a = new Array(10);
var b = a;
我们在内存中有这个(减去一些不相关的细节):
we have this in memory (minus a few irrelevant details):
a:Ref89895−−−+
|
| +−−−−−−−−−−−−−−−+
+−−−−−>| array |
| +−−−−−−−−−−−−−−−+
| | length: 10 |
b:Ref89895−−−+ +−−−−−−−−−−−−−−−+
a
和 b
包含一个引用,我在这里显示为Ref89895,尽管我们从未看到实际值。这是由 b = a
复制的,而不是数组本身。
a
and b
contain a reference, which I've shown here as Ref89895 although we never see the actual value. That's what's copied by b = a
, not the array itself.
同样,当你这样做时:
var matrix = new Array(10).fill(new Array(10), 0);
你最终获得
+−−−−−−−−−−−−−−−+
matrix:Ref89895−−−>| array |
+−−−−−−−−−−−−−−−+
| length: 10 |
| 0: Ref55462 |--\
| 1: Ref55462 |--\\
| 2: Ref55462 |--\\\
| 3: Ref55462 |--\\\\ +−−−−−−−−−−−−−−−+
| 4: Ref55462 |---+++++->| array |
| 5: Ref55462 |--///// +−−−−−−−−−−−−−−−+
| 6: Ref55462 |--//// | length: 10 |
| 7: Ref55462 |--/// +−−−−−−−−−−−−−−−+
| 8: Ref55462 |--//
| 9: Ref55462 |--/
+−−−−−−−−−−−−−−−+
要创建一个10位数组,其中10个位置中的每一个本身都是10位数组,我可能使用 Array.from
或使用
:地图填写
地图
To create a 10-place array where each of the 10 places is itself a 10-place array of 0, I'd probably use either Array.from
or fill
with map
:
// Array.from
var matrix = Array.from({length: 10}, function() {
return new Array(10).fill(0);
});
// fill and map
var matrix = new Array(10).fill().map(function() {
return new Array(10).fill(0);
});
或在ES2015中:
// Array.from
let matrix = Array.from({length: 10}, () => new Array(10).fill(0));
// fill and map
let matrix = new Array(10).fill().map(() => new Array(10).fill(0));
这篇关于JavaScript - 为什么Array.prototype.fill实际上填充了“指针”?填充“new Object()”之类的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!