0

I have a piece of code and it does not work as I expected. I have created an Array and I have copied it to a new one. I expected that the 2nd one would not change its value when the 1st one does it, but it seems that it does it. How could I avoid? I would like to print the initial value after pressing "Reset", but the value of aux has changed when the value of arrayStringDates2 changed.

var arrayStringDates2 = ["10/01/2017", "20/01/2018", "16/12/2015"];
var aux = arrayStringDates2;
document.getElementById("arrayStringDates2").innerHTML = arrayStringDates2;

document.addEventListener('click', function(event) {
  if (event.target.id == "format2") {
    for (i = 0; i < arrayStringDates2.length; i++) {
      arrayStringDates2[i] = arrayStringDates2[i].replace(/["/"]/gi, "");
    }
    document.getElementById("arrayStringDates2").innerHTML = arrayStringDates2;
  }
  if (event.target.id == "resetFormat") {
    console.log(aux)
    document.getElementById("arrayStringDates2").innerHTML = aux;
  }
}, false);
<button id="format2">
  Format
 </button>
<button id="resetFormat">
  Reset
 </button>
<div id="arrayStringDates2"></div>
phuzi
  • 12,078
  • 3
  • 26
  • 50
bellotas
  • 2,349
  • 8
  • 29
  • 60
  • 2
    you can use the spread operator `...` for that ex: `var ar1 = ['1','2','3']; var ar2 = [...ar1];` the spread operator will create a copy of the first array `ar1` to `ar2` and will not effect the if any changes happen in `ar1`; – vikscool Aug 09 '18 at 09:24
  • `var aux = arrayStringDates2` **does not** create a copy. – jonrsharpe Aug 09 '18 at 09:25
  • You might find this useful: https://stackoverflow.com/questions/6605640/javascript-by-reference-vs-by-value – Rafael Herscovici Aug 09 '18 at 09:25
  • More to read: https://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language – Rafael Herscovici Aug 09 '18 at 09:28

5 Answers5

3

aux have the same pointer references, to clone it you can use slice method.

var arrayStringDates2 = ["10/01/2017", "20/01/2018", "16/12/2015"];
var aux = arrayStringDates2.slice()
Arup Rakshit
  • 116,827
  • 30
  • 260
  • 317
Endless
  • 34,080
  • 13
  • 108
  • 131
0

To copy an array one of the simplest methods is .slice().

But this only creates a copy of the array, not of the non-primitive values inside, so strings or numbers would be duplicated, whereas objects would be the same in both copies of the array.

Use it like:

var arrayStringDates2 = ["10/01/2017", "20/01/2018", "16/12/2015"];
var aux = arrayStringDates2.slice()
Sebastian Speitel
  • 7,166
  • 2
  • 19
  • 38
0

It's not doing what you think it is...

var arrayStringDates2 = ["10/01/2017", "20/01/2018", "16/12/2015"];
var aux = arrayStringDates2;

Doesn't create a copy of the array, it just creates 2 references to the same array - arrayStringDates2 and aux both point to ["10/01/2017", "20/01/2018", "16/12/2015"]

What you need to do is create a new array with the same contents. So that changing one value only changes it in on of the arrays.

Array.prototype.slice is what you want.

var arrayStringDates2 = ["10/01/2017", "20/01/2018", "16/12/2015"];
var aux = arrayStringDates2.slice(); // shallow copy each item in arrayStringDates2 in to a new array

document.getElementById("arrayStringDates2").innerHTML = arrayStringDates2;

document.addEventListener('click', function(event) {
  if (event.target.id == "format2") {
    for (i = 0; i < arrayStringDates2.length; i++) {
      arrayStringDates2[i] = arrayStringDates2[i].replace(/["/"]/gi, "");
    }
    document.getElementById("arrayStringDates2").innerHTML = arrayStringDates2;
  }
  if (event.target.id == "resetFormat") {
    console.log(aux)
    document.getElementById("arrayStringDates2").innerHTML = aux;
  }
}, false);
<button id="format2">
  Format
 </button>
<button id="resetFormat">
  Reset
 </button>
<div id="arrayStringDates2"></div>
phuzi
  • 12,078
  • 3
  • 26
  • 50
0

I have a piece of code and it does not work as I expected. I have created an Array and I have copied it to a new one. I expected that the 2nd one would not change its value when the 1st one does it, but it seems that it does it.

This is due to the way JavaScript deals with memory.

For primitives (boolean, null, undefined, number, string, symbol) JavaScript passes the value of a variable (pass by value) If you assign a variable containing one of these types to a new variable. The value will be copied.

For complex objects (which an Array is) Javascript passes a reference to a value in memory (pass by reference). The actual value can be targeted by multiple references and is technically shared. If you assign a variable containing an Object type to a new variable, only the reference to that place in memory is copied.

JavaScript does this to be more memory efficient but it results in the behaviour you're describing. If you change an object, all variables pointing to that object will see the same effect.

How could I avoid?

What you wan't to do is clone the object so it get's it's own place in memory. There are many ways of cloning depending on your use case.

The internet is full with articles describing use cases and solutions, for instance see: https://davidwalsh.name/javascript-clone-array

Sven van de Scheur
  • 1,809
  • 2
  • 15
  • 31
0

For the blink browsers slice is the fastest method to duplicate an array. however for non blink browsers you can use while loop or for in loop.

Using Slice Method:

var newArray = myArray.slice();

Also, One of the Simplest way of duplicating array in ES6 is using array spread.

var newArray = [...myArray];

** These methods are copying array but if the array consists of the objects then they are still referenced and will change with the change in original.

onejeet
  • 1,191
  • 6
  • 14