.push() 覆盖 Javascript 中的数组值
.push() overwrites array values in Javascript
我查看了“类似问题”,但我要么不理解答案,要么似乎与这个问题不相关。
在某些情况下,我尝试时似乎无法覆盖数组值 (Loop3),而在其他情况下,数组值在我认为不应该被覆盖时被覆盖 (Loop4)。我刚刚编辑了代码以在各个点显示更多值。
<script>
function manual() {
myArray = [];
td=[1,2,3];
myArray.push(td);
td=[4,5,6];
myArray.push(td);
alert(myArray[0]); // Properly reports [1,2,3]
}
function loop() {
myArray = [];
td = [];
for (i=0; i<=1; i++) {
if (i==0) td=[1,2,3];
else if (i==1) td=[4,5,6];
myArray.push(td);
}
alert(myArray[0]); // Properly reports [1,2,3]
}
function loop2() {
myArray = [];
td = [];
for (i=0; i<=1; i++) {
td[i] = 9;
}
td = [1,2,3]; // Attempt to overwrite existing values
myArray.push(td);
alert(myArray[0]); // Properly returns 1,2,3
}
function loop3() {
myArray = [];
td = [];
for (i=0; i<=1; i++) {
for (j=0; j<=2; j++) {
td[j] = 9;
}
if (i==0) td=[1,2,3];
else if (i==1) td=[4,5,6];
myArray.push(td);
}
alert(myArray[0]); // Returns 9,9,9 when I expect 1,2,3
}
function loop4() {
myArray = [];
td = [];
tb = document.getElementById('myTable');
for (i=0; row = tb.rows[i]; i++) {
for (j = 0; col = row.cells[j]; j++) {
td[j] = col.innerHTML;
}
alert("td="+td); // Properly get 1,2,3 the 1st time, 4,5,6 the 2nd time
myArray.push(td);
alert(myArray); // Expect 1,2,3 the 1st run, and that's what I get
// Expect 1,2,3 | 4,5,6 the 2nd run, but get 4,5,6 | 4,5,6
}
}
</script>
<table id=myTable>
<tr><td>1</td><td>2</td><td>3</td></tr>
<tr><td>4</td><td>5</td><td>6</td></tr>
</table>
<button onclick=manual()>Manual</button>
<button onclick=loop()>Loop</button>
<button onclick=loop2()>Loop2</button>
<button onclick=loop3()>Loop3</button>
<button onclick=loop4()>Loop4</button>
在函数 4 中,您覆盖了数组元素。因为在第二个你输入两次。第一个你的数组填充 1,2,3 然后第二个填充 4,5,6 最后的结果是 4,5,6
如果你想要 1,2,3,你可以检查你的数组是否为空
function loop4() {
myArray = [];
td = [];
tb = document.getElementById('myTable');
for (i=0; row = tb.rows[i]; i++) {
for (j = 0; col = row.cells[j]; j++) {
td[j] = td[j] ? td[j] : col.innerHTML;
}
myArray.push(td);
}
console.log(myArray[0]); // Expect 1,2,3, actually get 4,5,6
}
<table id="myTable">
<tr><td>1</td><td>2</td><td>3</td></tr>
<tr><td>4</td><td>5</td><td>6</td></tr>
</table>
<button onclick="manual()">Manual</button>
<button onclick="loop()">Loop</button>
<button onclick="loop2()">Loop2</button>
<button onclick="loop3()">Loop3</button>
<button onclick="loop4()">Loop4</button>
您应该初始化循环索引,如下所示:for (var i=0; i<=1; i++)
这不是 Array 的内置方法 push()
的问题,问题是您正在改变 td
数组。以loop3
为例:
- 在
i=0
迭代结束时,td
然后是 [1,2,3]
,而 myArray
是 [[1,2,3]]
- 它存储绑定到 td
- 在
i=1
迭代开始时,在 j
循环之后(您在其中改变了先前的数组引用,它由 td
绑定),td
然后是 [9,9,9]
并且 myArray
(保存该数组引用)也会受到影响,导致 [[9,9,9]]
function mutatedLoop3() {
myArray = []
td = []
for (i = 0; i <= 1; i++) {
console.log('previous td', JSON.stringify(td))
for (j = 0; j <= 2; j++) {
td[j] = 9
}
console.log('mutated td', JSON.stringify(td))
if (i == 0) td = [1, 2, 3] // you reassign to a new array, means new reference
else if (i == 1) td = [4, 5, 6]
myArray.push(td)
console.log(JSON.stringify(td), JSON.stringify(myArray))
console.log('---')
}
console.log(myArray[0]) // Returns 9,9,9 when I expect 1,2,3
}
function fixedLoop3() {
myArray = []
for (i = 0; i <= 1; i++) {
td = [] // now it is reset every iteration
for (j = 0; j <= 2; j++) {
td[j] = 9
}
if (i == 0) td = [1, 2, 3]
else if (i == 1) td = [4, 5, 6]
myArray.push(td)
console.log(JSON.stringify(td), JSON.stringify(myArray))
console.log('---')
}
console.log(myArray[0]) // Returns 9,9,9 when I expect 1,2,3
}
mutatedLoop3()
fixedLoop3()
我明白了。答案在这里。
// When you push an array or array element to another array,
// you don't copy the *data* to the new array;
// you copy a *reference* to the original array or array element.
// If you change the elements of the original array,
// the elements you pushed also change.
main = [];
sub = [1,2,3];
main.push(sub); // main now contains 1,2,3 as a *reference* to the sub
sub[0]=9;
alert(main); // Contains 9,2,3
//------------------------------------------------------------------------------------
// Redefining the original array destroys the link/reference.
//------------------------------------------------------------------------------------
main = [];
sub = [1,2,3];
main.push(sub); // main now contains 1,2,3 as a *reference* to sub
sub = []; // sub has been redefined, destroying the link.
sub[0]=9;
alert(main); // Contains 1,2,3
//------------------------------------------------------------------------------------
// Setting the values for a whole array redefines it, destroying the links.
//------------------------------------------------------------------------------------
main = []; // Redefines the array, destroying links
main = [4,5,6]; // Providing initial values redefines the array, too
// (destroying links).
//------------------------------------------------------------------------------------
// Changing the value of an element is *not* a redefinition of the array,
// so links persist.
//------------------------------------------------------------------------------------
main = [];
sub = [1,2,3];
main.push(sub); // main now contains 1,2,3 as a *reference* to sub
sub[0]=9; // Does not redefine main, only changes one of its element. Refs remain intact.
alert(main); // Contains 9,2,3
我查看了“类似问题”,但我要么不理解答案,要么似乎与这个问题不相关。
在某些情况下,我尝试时似乎无法覆盖数组值 (Loop3),而在其他情况下,数组值在我认为不应该被覆盖时被覆盖 (Loop4)。我刚刚编辑了代码以在各个点显示更多值。
<script>
function manual() {
myArray = [];
td=[1,2,3];
myArray.push(td);
td=[4,5,6];
myArray.push(td);
alert(myArray[0]); // Properly reports [1,2,3]
}
function loop() {
myArray = [];
td = [];
for (i=0; i<=1; i++) {
if (i==0) td=[1,2,3];
else if (i==1) td=[4,5,6];
myArray.push(td);
}
alert(myArray[0]); // Properly reports [1,2,3]
}
function loop2() {
myArray = [];
td = [];
for (i=0; i<=1; i++) {
td[i] = 9;
}
td = [1,2,3]; // Attempt to overwrite existing values
myArray.push(td);
alert(myArray[0]); // Properly returns 1,2,3
}
function loop3() {
myArray = [];
td = [];
for (i=0; i<=1; i++) {
for (j=0; j<=2; j++) {
td[j] = 9;
}
if (i==0) td=[1,2,3];
else if (i==1) td=[4,5,6];
myArray.push(td);
}
alert(myArray[0]); // Returns 9,9,9 when I expect 1,2,3
}
function loop4() {
myArray = [];
td = [];
tb = document.getElementById('myTable');
for (i=0; row = tb.rows[i]; i++) {
for (j = 0; col = row.cells[j]; j++) {
td[j] = col.innerHTML;
}
alert("td="+td); // Properly get 1,2,3 the 1st time, 4,5,6 the 2nd time
myArray.push(td);
alert(myArray); // Expect 1,2,3 the 1st run, and that's what I get
// Expect 1,2,3 | 4,5,6 the 2nd run, but get 4,5,6 | 4,5,6
}
}
</script>
<table id=myTable>
<tr><td>1</td><td>2</td><td>3</td></tr>
<tr><td>4</td><td>5</td><td>6</td></tr>
</table>
<button onclick=manual()>Manual</button>
<button onclick=loop()>Loop</button>
<button onclick=loop2()>Loop2</button>
<button onclick=loop3()>Loop3</button>
<button onclick=loop4()>Loop4</button>
在函数 4 中,您覆盖了数组元素。因为在第二个你输入两次。第一个你的数组填充 1,2,3 然后第二个填充 4,5,6 最后的结果是 4,5,6
如果你想要 1,2,3,你可以检查你的数组是否为空
function loop4() {
myArray = [];
td = [];
tb = document.getElementById('myTable');
for (i=0; row = tb.rows[i]; i++) {
for (j = 0; col = row.cells[j]; j++) {
td[j] = td[j] ? td[j] : col.innerHTML;
}
myArray.push(td);
}
console.log(myArray[0]); // Expect 1,2,3, actually get 4,5,6
}
<table id="myTable">
<tr><td>1</td><td>2</td><td>3</td></tr>
<tr><td>4</td><td>5</td><td>6</td></tr>
</table>
<button onclick="manual()">Manual</button>
<button onclick="loop()">Loop</button>
<button onclick="loop2()">Loop2</button>
<button onclick="loop3()">Loop3</button>
<button onclick="loop4()">Loop4</button>
您应该初始化循环索引,如下所示:for (var i=0; i<=1; i++)
这不是 Array 的内置方法 push()
的问题,问题是您正在改变 td
数组。以loop3
为例:
- 在
i=0
迭代结束时,td
然后是[1,2,3]
,而myArray
是[[1,2,3]]
- 它存储绑定到td
- 在
i=1
迭代开始时,在j
循环之后(您在其中改变了先前的数组引用,它由td
绑定),td
然后是[9,9,9]
并且myArray
(保存该数组引用)也会受到影响,导致[[9,9,9]]
function mutatedLoop3() {
myArray = []
td = []
for (i = 0; i <= 1; i++) {
console.log('previous td', JSON.stringify(td))
for (j = 0; j <= 2; j++) {
td[j] = 9
}
console.log('mutated td', JSON.stringify(td))
if (i == 0) td = [1, 2, 3] // you reassign to a new array, means new reference
else if (i == 1) td = [4, 5, 6]
myArray.push(td)
console.log(JSON.stringify(td), JSON.stringify(myArray))
console.log('---')
}
console.log(myArray[0]) // Returns 9,9,9 when I expect 1,2,3
}
function fixedLoop3() {
myArray = []
for (i = 0; i <= 1; i++) {
td = [] // now it is reset every iteration
for (j = 0; j <= 2; j++) {
td[j] = 9
}
if (i == 0) td = [1, 2, 3]
else if (i == 1) td = [4, 5, 6]
myArray.push(td)
console.log(JSON.stringify(td), JSON.stringify(myArray))
console.log('---')
}
console.log(myArray[0]) // Returns 9,9,9 when I expect 1,2,3
}
mutatedLoop3()
fixedLoop3()
我明白了。答案在这里。
// When you push an array or array element to another array,
// you don't copy the *data* to the new array;
// you copy a *reference* to the original array or array element.
// If you change the elements of the original array,
// the elements you pushed also change.
main = [];
sub = [1,2,3];
main.push(sub); // main now contains 1,2,3 as a *reference* to the sub
sub[0]=9;
alert(main); // Contains 9,2,3
//------------------------------------------------------------------------------------
// Redefining the original array destroys the link/reference.
//------------------------------------------------------------------------------------
main = [];
sub = [1,2,3];
main.push(sub); // main now contains 1,2,3 as a *reference* to sub
sub = []; // sub has been redefined, destroying the link.
sub[0]=9;
alert(main); // Contains 1,2,3
//------------------------------------------------------------------------------------
// Setting the values for a whole array redefines it, destroying the links.
//------------------------------------------------------------------------------------
main = []; // Redefines the array, destroying links
main = [4,5,6]; // Providing initial values redefines the array, too
// (destroying links).
//------------------------------------------------------------------------------------
// Changing the value of an element is *not* a redefinition of the array,
// so links persist.
//------------------------------------------------------------------------------------
main = [];
sub = [1,2,3];
main.push(sub); // main now contains 1,2,3 as a *reference* to sub
sub[0]=9; // Does not redefine main, only changes one of its element. Refs remain intact.
alert(main); // Contains 9,2,3