简体   繁体   English

array.push似乎替换了先前的对象,而不是附加

[英]array.push seems to replace previous object rather than append

I want to collect coordinates for rectangles I'm drawing across canvas area. 我想收集在画布上绘制的矩形的坐标。 When I push the next set of coords into my array, each of the previous entries in the array become the new set, rather than remaining as their original coords. 当我将下一组坐标插入到数组中时,数组中的每个先前条目将成为新的一组,而不是保留为原始坐标。

I'm a one-week veteran of javascript so I'm pretty sure this is a newbie question. 我是一个为期一周的javascript老手,所以我很确定这是一个新手问题。 I'm replacing a small Excel VBA I wrote to demo an algebra concept for my students because not every student has Excel on their computer, and the online version of Excel doesn't run VBA macros. 我正在替换为演示给学生演示代数概念而编写的一个小型Excel VBA,因为并非每个学生的计算机上都具有Excel,并且Excel的在线版本不运行VBA宏。 I want a stand-alone app they can download and run offline. 我想要一个可以下载并脱机运行的独立应用程序。 I have no problem drawing the rectangles. 我画矩形没有问题。 I want arr(ndx) to contain the coordinates of the ndx-th rectangle. 我希望arr(ndx)包含第ndx个矩形的坐标。 Ultimately if a student selects a set of rectangles I will change the background color of that set. 最终,如果学生选择了一组矩形,我将更改该矩形的背景色。 My console output shows that on the ndx-th iteration, all the arr entries from 0 to ndx contain the same set of coordinates, the last one that was captured. 我的控制台输出显示,在第ndx次迭代中,从0到ndx的所有arr条目都包含同一组坐标,即最后一个被捕获的坐标。 To me it looks like arr.push is over-writing each previous entry with the current one, rather than appending them to the array. 在我看来,arr.push正在用当前条目覆盖每个先前的条目,而不是将它们附加到数组中。 What am I missing? 我想念什么? I've gutted my code just to illustrate the problem I'm having. 我删除了代码只是为了说明我遇到的问题。 Included console.log code for last part of output block. 输出块最后一部分的随附console.log代码。

var arr = [];  var ndx = 0;   //array to contain rectangle coords  

Rows = 2; Cols = 3;           //Actual 40 X 60 or so.  
for (j=0; j<Rows;j++) {  
    for (i=0; i<Cols; i++) {  
        obj.row = j; obj.col = i;
        obj.xpos = obj.xpos + obj.xpos * j;     
        obj.ypos = obj.ypos + obj.ypos * i;  

        // will actually use fillRect() here to draw  
        //grid of rectangles spread across screen.  This works.  

        arr.push({obj});    // capture rect's coords for later reference  

        watchit0 = Object.entries(arr[ndx].obj);    //for debugging  
        if (ndx > 0) {  
            watchit1 = Object.entries(arr[ndx - 1].obj); }  
        else {  
            watchit1 = "                          ";  
        }  

        watchit2 = Object.keys(arr);    
        console.log("obj: " + Object.entries(obj)  
+ "     arr: " + watchit0 + "    arr-1: "  
+ watchit1 + "    keys: " + watchit2);

        ndx++;  
    }  
}  

//everything below is for debugging  
console.log("  ");  

watchit00 = Object.entries(arr[0].obj);  
watchit01 = Object.entries(arr[1].obj);  
watchit02 = Object.entries(arr[2].obj);  
watchit03 = Object.entries(arr[3].obj);  
watchit04 = Object.entries(arr[4].obj);  
watchit05 = Object.entries(arr[5].obj);  

console.log("     0: " + watchit00 + "     1:  " + watchit01);  
console.log("     2: " + watchit02 + "     3:  " + watchit03);  
console.log("     4: " + watchit04 + "     5:  " + watchit05);

console.log output (reformatted): console.log输出(重新格式化):

obj: row,0,col,0,xpos,1,ypos,10       
arr: row,0,col,0,xpos,1,ypos,10       arr-1:                                                       keys: 0

obj: row,0,col,1,xpos,1,ypos,20       
arr: row,0,col,1,xpos,1,ypos,20       arr-1: row,0,col,1,xpos,1,ypos,20       keys: 0,1

obj: row,0,col,2,xpos,1,ypos,60       
arr: row,0,col,2,xpos,1,ypos,60       arr-1: row,0,col,2,xpos,1,ypos,60       keys: 0,1,2

obj: row,1,col,0,xpos,2,ypos,60       
arr: row,1,col,0,xpos,2,ypos,60       arr-1: row,1,col,0,xpos,2,ypos,60       keys: 0,1,2,3

obj: row,1,col,1,xpos,4,ypos,120     
arr: row,1,col,1,xpos,4,ypos,120     arr-1: row,1,col,1,xpos,4,ypos,120    keys: 0,1,2,3,4

obj: row,1,col,2,xpos,8,ypos,360     
arr: row,1,col,2,xpos,8,ypos,360     arr-1: row,1,col,2,xpos,8,ypos,360    keys: 0,1,2,3,4,5

What's below is output arr[ndx] at the end of my code. 下面是我代码末尾的输出arr[ndx] I'm expecting the 6 entries to match obj: above but every entry is the last iteration. 我期望6个条目与上面的obj:相匹配,但是每个条目都是最后一次迭代。 Why?? 为什么??

0:  row,1,col,2,xpos,8,ypos,360     
1:  row,1,col,2,xpos,8,ypos,360     
2:  row,1,col,2,xpos,8,ypos,360     
3:  row,1,col,2,xpos,8,ypos,360   
4:  row,1,col,2,xpos,8,ypos,360     
5:  row,1,col,2,xpos,8,ypos,360

Here Steve. 史蒂夫。 The first code shows a simplified version of where you are going wrong. 第一个代码显示了错误原因的简化版本。 NOTE: if you were to do a test, each object in the Array would be the same object. 注意:如果要进行测试,则数组中的每个对象都是相同的对象。

The second shot at the code shows using Object.create on our object function to get a new instance. 该代码的第二张照片显示了在对象函数上使用Object.create获取新实例。

Hope this helps. 希望这可以帮助。

 let sampleArrValues = [1,2,3,4,5]; function myObject(num) { this.number = num; } console.log('Bad Array Demo'); // This wont work let badArray = []; var obj = new myObject(1); sampleArrValues.forEach(num => { obj.number = num; badArray.push(obj); }); // Lets look at the array content badArray.forEach(item => { console.log(item.number); }); // -> 5,5,5,5,5 console.log('Good Array Demo'); // Now do properly var goodArray = []; sampleArrValues.forEach(num => { obj = Object.create(myObject); obj.number = num; goodArray.push(obj); }); goodArray.forEach(item => { console.log(item.number); }); // -> 1,2,3,4,5 

Here is another attempt on the answers you already got: 这是您已经获得答案的另一种尝试:

  • first part of the snippet shows what you have, but usually you do not want: a single object is stored in the obj1 variable at the beginning, and it gets push -ed into arr1 after setting x to a different value. 片段的第一部分显示了您所拥有的,但是通常您不想要:一个对象最初存储在obj1变量中,并且在将x设置为其他值之后,它push入到arr1 The log lines in the console show that the push itself happens properly (the array grows), but as the same object is stored multiple times, the growing amount of content all shows the last value set via obj1.x 控制台中的日志行显示push本身已正确执行(数组增长),但是当同一对象多次存储时,不断增长的内容量都显示了通过obj1.x设置的最后一个值
  • second part of the snippet shows what you should do: it is very similar, but it initializes obj2 with a whole new object in each iteration, and thus not only the number of elements in the array grows, but they are also referring different objects with different content. 片段的第二部分显示了您应该执行的操作:非常相似,但是在每次迭代中它都会使用一个全新的对象来初始化obj2 ,因此不仅数组中的元素数量增加了,而且它们还引用了不同的对象不同的内容。

 var obj1={x:1, toString:function(){return this.x;}}; var arr1=[]; for(var i=0;i<5;i++){ obj1.x=i; arr1.push(obj1); console.log(arr1.join()); } console.log("---"); var arr2=[]; for(var i=0;i<5;i++){ var obj2={x:i, toString:function(){return this.x;}}; arr2.push(obj2); console.log(arr2.join()); } 

Side note: in the original code, arr.push({obj}); 旁注:在原始代码中, arr.push({obj}); is used, which does create a new object (it is a shorthand for arr.push({obj:obj}); ), the obj field of the newly created object always refer to the same, single object you have stored in obj somewhere at the beginning. 使用时,它的确创建了一个新对象(这是arr.push({obj:obj});的简写),新创建的对象的obj字段始终引用您存储在obj某个位置的同一单个对象一开始。

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

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