Javascript array.push似乎替换了以前的对象,而不是追加

Javascript array.push似乎替换了以前的对象,而不是追加,javascript,arrays,html5-canvas,Javascript,Arrays,Html5 Canvas,我想收集我在画布区域绘制的矩形的坐标。当我将下一组坐标推送到数组中时,数组中以前的每个条目都将成为新的坐标集,而不是保持原来的坐标 我在javascript方面有一周的经验,所以我很确定这是一个新手问题。我正在替换一个小的Excel VBA,我写这个小的Excel VBA是为了给我的学生演示一个代数概念,因为不是每个学生的计算机上都有Excel,而且Excel的在线版本不运行VBA宏。我想要一个他们可以下载并离线运行的独立应用程序。 我画矩形没有问题。我希望arr(ndx)包含ndx矩形的坐标。

我想收集我在画布区域绘制的矩形的坐标。当我将下一组坐标推送到数组中时,数组中以前的每个条目都将成为新的坐标集,而不是保持原来的坐标

我在javascript方面有一周的经验,所以我很确定这是一个新手问题。我正在替换一个小的Excel VBA,我写这个小的Excel VBA是为了给我的学生演示一个代数概念,因为不是每个学生的计算机上都有Excel,而且Excel的在线版本不运行VBA宏。我想要一个他们可以下载并离线运行的独立应用程序。 我画矩形没有问题。我希望arr(ndx)包含ndx矩形的坐标。最终,如果一个学生选择了一组矩形,我将改变该组的背景色。 我的控制台输出显示,在ndx第次迭代中,从0到ndx的所有arr条目都包含相同的坐标集,即最后捕获的坐标集。 在我看来,arr.push似乎是在用当前条目重写之前的每个条目,而不是将它们附加到数组中。我错过了什么? 我删除了我的代码,只是为了说明我遇到的问题。包含输出块最后一部分的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);
下面是代码末尾的输出
arr[ndx]
。 我希望这6个条目与上面的obj:匹配,但每个条目都是最后一次迭代。为什么

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
这是史蒂夫。 第一段代码显示了错误所在的简化版本。 注意:如果要进行测试,数组中的每个对象都将是相同的对象

代码的第二个镜头显示了在对象函数上使用Object.create来获得一个新实例

希望这有帮助

让sampleArrValues=[1,2,3,4,5];
函数myObject(num){
this.number=num;
}
log('Bad Array Demo');
//这行不通
设badArray=[];
var obj=新的myObject(1);
sampleArrValues.forEach(num=>{
obj.number=num;
推送(obj);
});
//让我们看看数组内容
badArray.forEach(项=>{
控制台日志(项目编号);
});
// -> 5,5,5,5,5
log('Good Array Demo');
//现在好好做
var goodArray=[];
sampleArrValues.forEach(num=>{
obj=Object.create(myObject);
obj.number=num;
goodArray.push(obj);
});
goodArray.forEach(项=>{
控制台日志(项目编号);
});

//->1,2,3,4,5
下面是对您已经得到的答案的另一次尝试:

  • 代码段的第一部分显示了您拥有的,但通常您不想要的内容:一个对象在开始时存储在
    obj1
    变量中,在将
    x
    设置为不同的值后,它将
    推入
    arr1
    。控制台中的日志行显示
    推送
    本身发生正确(数组增长),但由于同一对象被多次存储,不断增长的内容量都显示通过
    obj1.x设置的最后一个值
  • 代码片段的第二部分显示了您应该做的事情:它非常类似,但它在每次迭代中使用一个全新的对象初始化
    obj2
    ,因此不仅数组中的元素数量增加,而且它们还引用具有不同内容的不同对象
var obj1={x:1,
toString:function(){返回this.x;}};
var arr1=[];

对于(var i=0;i您是否考虑过格式化您的代码-如果看起来您在每个循环中都重用相同的
obj
,缩进使代码实际上是可读的(但它似乎没有在示例代码中的任何地方定义,因此很难确定)。我刚刚花了3个多小时试图格式化我的代码,让这个问题接受它。我愿意接受建议。使用Komodo ide自动格式化程序最终在这里得到它。我已经按照我所能想到的方式对它进行了格式化。抱歉-我在副本中遗漏了这一行。var obj={row:22,col:33,xpos:1,ypos:10}@标记-当我查看输出时,obj在每个循环上都会发生变化,arr(ndx)显示新值。但是,arr(ndx-1)也会显示新值,而不是在上一次循环中显示的值。这怎么可能呢?在我看来,一旦ndx步骤开始,arr(ndx-1)就会一成不变,除非我特别更改了arr(ndx-1)在将来的某个时候。obj不是一直保存我的数据直到我将其存储在arr(ndx)中吗?arr.push如何返回并更改arr(ndx-1)?显然我遗漏了一些东西。我应该如何处理obj?谢谢!我的测试代码工作正常(你知道会的!)我仍然需要消化我看到的东西,但至少我能让它工作。感谢你对什么不工作,什么工作。感谢你的回答。我会消化你的代码,它是在我实现Paul的答案时出现的。@SteveHarris主要区别在于
对象。create()
与simple
{}
。它们都创建了一个全新的独立对象,这是这里的关键部分。除此之外,
object.create()
创建原始对象的副本,其中包括可能的额外内容,如原型,或您想要保留但不想再次设置的字段。在这里,这种额外内容根本不存在,有3个字段,每个字段都有一个新值,这就是为什么我不觉得需要创建原始对象的副本。(而
toString()
部分仅用于提供作为输出的数字,而不是
[object object]
或类似的东西。实际上,这是可以通过
object.create()
保存的东西,只是在这里它并不是预期示例的一部分,它仅用于日志记录)
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