简体   繁体   English

.push() 覆盖 Javascript 中的数组值

[英].push() overwrites array values in Javascript

I checked the "Similar questions" but I either didn't understand the answers or they didn't seem relevant to this question.我检查了“类似问题”,但我要么不明白答案,要么它们似乎与这个问题无关。

In certain cases I can't seem to overwrite array values when I try (Loop3), and in others, the array values get overwritten when I think they shouldn't be (Loop4).在某些情况下,当我尝试(Loop3)时,我似乎无法覆盖数组值,而在其他情况下,当我认为它们不应该被覆盖时(Loop4),数组值会被覆盖。 I just edited the code to show more values at various points.我刚刚编辑了代码以在各个点显示更多值。

<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>

In function 4 you override your array element.在 function 4 中,您覆盖了数组元素。 Because in second for u enter two times.因为在第二个你输入两次。 First one your array fill with 1,2,3 then second one fill 4,5,6 and final result is 4,5,6第一个你的数组填充 1,2,3 然后第二个填充 4,5,6 最终结果是 4,5,6

you can check if empty or not to your array if you want 1,2,3如果你想要 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>

You should initialize your loop indexes, like so: for (var i=0; i<=1; i++)您应该初始化循环索引,如下所示: for (var i=0; i<=1; i++)

It is not the problem with the Array's build-in method push() , the problem is that you are mutating the td array.这不是数组的内置方法push()的问题,问题是您正在改变td数组。 Let's take loop3 for example:让我们以loop3为例:

  • at the end of i=0 iteration, td is then [1,2,3] , and myArray is [[1,2,3]] - which stores the array reference binded to tdi=0迭代结束时, td[1,2,3] ,而myArray[[1,2,3]] - 它存储绑定到td的数组引用
  • in the start of i=1 iteration, after the j loop (in which you mutated the previous array reference, which is bind by td ), the td is then [9,9,9] and the myArray (which hold that array reference) would also be affected, resulted in [[9,9,9]]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()

I figured it out.我想到了。 Here's the answer.这是答案。

 // 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM