array.push, кажется, заменяет предыдущий объект, а не добавляет - PullRequest
0 голосов
/ 28 декабря 2018

Я хочу собрать координаты для прямоугольников, которые я рисую по всей области холста.Когда я помещаю следующий набор координат в мой массив, каждая из предыдущих записей в массиве становится новым набором, а не остается их исходными координатами.

Я являюсь ветераном javascript на одну неделю, поэтомуЯ уверен, что это вопрос новичка.Я заменяю небольшой Excel VBA, который я написал, чтобы продемонстрировать концепцию алгебры для моих учеников, потому что не у каждого учащегося есть Excel на своем компьютере, а онлайн-версия Excel не запускает макросы VBA.Я хочу отдельное приложение, которое они могут загрузить и запустить в автономном режиме.У меня нет проблем с рисованием прямоугольников.Я хочу, чтобы arr (ndx) содержал координаты ndx-го прямоугольника.В конечном итоге, если ученик выберет набор прямоугольников, я изменю цвет фона этого набора.Вывод моей консоли показывает, что на ndx-й итерации все записи arr от 0 до ndx содержат одинаковый набор координат, последний из которых был захвачен.Мне кажется, что 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);

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

Ниже приведен вывод 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

Ответы [ 2 ]

0 голосов
/ 28 декабря 2018

Вот еще одна попытка ответов, которые вы уже получили:

  • Первая часть фрагмента показывает, что у вас есть, но обычно вы не хотите: один объект сохраняется в obj1переменная в начале, и она получает push -ed в arr1 после установки x другого значения.Журнальные строки в консоли показывают, что само push происходит правильно (массив увеличивается), но, поскольку один и тот же объект сохраняется несколько раз, растущее количество контента показывает последнее значение, установленное с помощью obj1.x
  • вторая часть фрагмента показывает, что вы должны делать: она очень похожа, но она инициализирует 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());
}

Примечание: в исходном коде используется arr.push({obj});, который создает новый объект (это сокращение для arr.push({obj:obj});), objполе вновь созданного объекта всегда ссылается на один и тот же объект, который вы сохранили в obj где-то в начале.

0 голосов
/ 28 декабря 2018

Здесь Стив.Первый код показывает упрощенную версию, где вы идете не так.ПРИМЕЧАНИЕ: если бы вы делали тест, каждый объект в массиве был бы одним и тем же объектом.

Второй фрагмент кода показывает использование Object.create в нашей объектной функции для получения нового экземпляра.

Надеюсь, это поможет.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...