Ariel Catli
Ariel Catli

Reputation: 43

Can I reassign a new array to an array variable in JavaScript?

I have a problem with arrays in JavaScript and manipulating them inside a function.
This is an exercise from the book Eloquent JavaScript. It is about two functions:

Inside reverseArrayInPlace(), I just called reverseArray() to create a new array and reassign to the argument of reverserArrayInPlace(). However, when I get to display the passed array, the reassignment is not reflected to the array passed.
I thought arrays in JavaScript are always passed by reference?

I have also tried to reassign an array variable to another array and it was successful if done outside a function. What could be the problem?
By the way, the exercise forbids the use of the reverse() method in JavaScript.

function reverseArray(array) {
  var new_array = [];
  for (var i = array.length-1; i >= 0; i--)
    new_array.push(array[i]);
  return new_array;
}

function reverseArrayInPlace(array) {
  array = reverseArray(array);
}
	
var r1 = [1,2,3,4,5,6,7,8,9,10];

console.log("r1 ", r1.join(",")); 
// → 1,2,3,4,5,6,7,8,9,10

console.log("reverse of r1 ", reverseArray(r1).join(","));
// → 10,9,8,7,6,5,4,3,2,1

console.log("r1 ", r1.join(","));
// → 1,2,3,4,5,6,7,8,9,10

reverseArrayInPlace(r1);
// the changes are not reflected here

console.log("r1 reversed in place ", r1.join(",")); 
// → still 1,2,3,4,5,6,7,8,9,10;
// this should display r1 = 10,9,8,7,6,5,4,3,2,1

Upvotes: 1

Views: 6020

Answers (1)

theAlexandrian
theAlexandrian

Reputation: 908

The variable array of your function reverseArrayInPlace is local to that function. Thus, assigning to it just makes the scope forget about the previous value which was the array r1.

Consider the following :

var a = 5;
function change(a) {
  // Inner 'a'
  a = 0;
  console.log("inside change : ", a);
}

// Outer 'a'
change(a); // → 0
console.log("outside change : ", a); // → 5

You can see that although both the global scope and change's scope use the same name a, they are not the same variables. Assigning to a inside change will never affect the outer a.

HOWEVER
For an object (or everything that's an instance of Object.prototype, like an array), changing the properties inside a function will effectively change it outside.

To fully understand this, look at the following carefully :

var o = {
  arr1: [1, 2, 3],
  arr2: [1, 2, 3],
  str: "foo",
  num: 1
};

console.log("before changing : ", o);

function change(a) {
  // Reassigning to properties of 'a'
  a.arr1[0] = 0;
  a.arr2 = [ "destroyed" ];
  a.str += " bar";
  a.num = a.num * 15;
  
  // Reassigning to 'a'
  a = { change: "Destroyed !" };
  
  console.log("inside change : ", a);
}


change(o); // → { change: "Destroyed !" }
console.log("outside change : ", o); // → initial 'o' with modified properties.

Assigning to a = { change: "Destroyed !" }; still did not affect o. But all the changes to o's properties were applied.

As you can see, the final result of changing o gives :

{
  arr1: [0, 1, 3],     // First item changed.
  arr2: ["destroyed"], // It's a completely new array.
  str: "foo bar",      // " bar" was added.
  num: 15              // 1 * 15
}

Upvotes: 2

Related Questions