8

I have an array of objects with length n and I want to extend it to the length n+1. For ease of use I would like to duplicate the last element and then change the properties of the duplicate.

let arr = [{id: 1, name: 'foo'}, {id: 2, name: 'bar'}];

arr.push(arr[1]);       // extend by copying the last
arr[2].id += 1;         // change the id of the new last
arr[2].name = 'foobar'; // change the name of the new last

console.log(arr);

In the snippet above (use the browser console as snippet console is behaving kinda weird here) is what I've tried but for some reason any change to the copied/new last element is also applied to the original/old last/new second-last element in the array.

How can I properly do this and why does my code behave in the way it does?

leonheess
  • 16,068
  • 14
  • 77
  • 112

2 Answers2

4

You could push a copy of the object and omit the same object reference.

let arr = [{id: 1, name: 'foo'}, {id: 2, name: 'bar'}];

arr.push({ ...arr[1] }); // extend by copying the last
arr[2].id += 1;          // change the id of the new last
arr[2].name = 'foobar';  // change the name of the new last

console.log(arr);
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • 2
    `...arr[1]`, spreads all the keys and values from the existing object into a new one, that's why you are not having that issue with referencing anymore, good answer :) – Nicolae Maties Jul 29 '19 at 13:30
  • 2
    Also please be careful while cloning with spread operator. It goes only 1 level deep with cloning. In your case its fine. – ambianBeing Jul 29 '19 at 13:36
1

const arr = [{id: 1, name: 'foo'}, {id: 2, name: 'bar'}];
const lastEl = Object.assign({}, arr[1]);
lastEl.id = 4;
lastEl.name = 'foo';
arr.push(lastEl);
console.log(arr);
Nicolae Maties
  • 2,476
  • 1
  • 16
  • 26