Variable reference in Javascript

Asked

Viewed 115 times

5

To generate the following matrix:

1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5

Consider the following code for constructing a matrix with equal lines:

var linha = [1, 2, 3, 4];
var matriz = [linha, linha, linha ];
matriz[3] = linha ;      // outra alternativa
matriz.push(linha);      // mais outro modo

It seems logical to use this code to generate the matrix. But we have one however, we are adding elements by reference in the Array matriz.

If we try

matriz[0].push();       // retirar o elemento na posição A[0][4]
matriz[1][1] = 10;      // alterarmos A[1][1] de 2 para 10

replicate changes to all lines.

I would like you to tell me about this Javascript behavior:

  • The problems that careless use can entail, and
  • What is the simplest and most acceptable way to create this matrix and make these changes to it.

1 answer

5


If you want to change values independently, you need something like this:

var linha = [1, 2, 3, 4, 5];
var matriz = [];

for( var i = 0; i<5; i++ ) {
   matriz.push( linha.slice() );
}

//testando alteração:
matriz[2][2] = 999;

for( var i = 0; i<5; i++ ) {
  body_log( 'matriz[' + i + ']:' + matriz[i] );
}


// só pra nao precisar de console:
function body_log(msg) {
  document.body.innerHTML = document.body.innerHTML + '<p>' + msg + '</p>';
}

What’s going on here is that the .slice() is one of the ways to produce a clone of a array, and not a new reference.

As you yourself mentioned, when someone does umaVariavel = umArray in JS, is simply saying that umaVariavel points to the same memory space as umArray, And the consequence is that when you access either of those two things, you’re seeing the same data. Any changes made, whether by a name or another, will be reflected when accessing them.

The same thing happens when you point out a sub-index of array to another array. That sub-index will be pointing to the same space as the original variable.


Behavior in recursiveness

The following example is to confuse some and worry others. Try to endender what happens when you not only use arrays by reference, makes the reference within the array:

var matriz = [];
matriz.push( [00, 01, 02,     03, 04, 05] );
matriz.push( [10, 11, 12,     13, 14, 15] );
matriz.push( [20, 21, 22,     23, 24, 25] );
matriz.push( [30, 31, 32, matriz, 34, 35] );
matriz.push( [40, 41, 42,     43, 44, 45] );
matriz.push( [50, 51, 52,     53, 54, 55] );

body_log( 'matriz[1][1]      <br>' + matriz[1][1] );
body_log( 'matriz[2][2]      <br>' + matriz[2][2] );
body_log( 'matriz[3][3]      <br>' + matriz[3][3] );
body_log( 'matriz[3][3][2]   <br>' + matriz[3][3][2] );
body_log( 'matriz[3][3][1][2]<br>' + matriz[3][3][1][2] );

// alterando:
matriz[3][3][1][2] = 999;
body_log( 'matriz[3][3][1][2] = 999<br>');
body_log( 'resultado:<br>' + matriz );

matriz[0][0] = matriz[3];
matriz[3][3][0][0][3][4] = "que?";

body_log( 'matriz[0][0] = matriz[3] e matriz[3][3][0][0][3][4] = "que?"' );
body_log( 'resultado:<br>' + matriz );

function body_log(msg) { document.body.innerHTML = document.body.innerHTML + '<p>' + msg + '</p>'; }

Understands how the array can access itself through one of its members? I hope you are seeing this example in a browser well implemented, which simply hides member 3.3 of the array, otherwise it will collapse.

Note that by modifying the member [3][3][1][2] of the matrix we are actually modifying the member [1][2], because the member [3][3] is itself array.

To "make it worse", I added an alteration transforming the item [0][0] on line 3 of the matrix, and changing one of its members, and changing the line 4 whole to a string, through three recursions. For those who like to play Portal, it’s easy to understand.

Imagine in a real case the kind of confusion you can make when you don’t know the difference between a true value and a mere reference.

  • 3

    That its function body_log should be default to Stack Snippets.

  • I always thought about it, even in Jsfiddle :)

  • Good to remember that the slice does not delete the reference when an Array element is an Object. :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.