joshualan
joshualan

Reputation: 2140

Why does this JavaScript code make the entire array point to the same object?

In the book Javascript: The Good Parts, there is this code on page 64:

for (i = 0; i < n; i += 1) {
 my_array[i] = [];
}
// Note: Array.dim(n, []) will not work here.
// Each element would get a reference to the same
// array, which would be very bad.

Why would each element in the array point to the same object? It seems to me that the line my_array[i] = []; be reevaluated each loop, causing a new empty object to be created.

What're the rules of getting a reference to the same object versus a new one? How would I make this get a different empty array every loop?

EDIT: Reading people's responses, I just read the paragraph wrong. Thanks for all the answers!

Upvotes: 0

Views: 91

Answers (3)

Let Me Tink About It
Let Me Tink About It

Reputation: 16122

The premise of your question is incorrect:

Why would each element in the array point to the same object?

It doesn't. Each loop populates the i th element of the main array with a new and distinct empty array. See this jsBin.

http://jsbin.com/zudiwamice/edit?js,console,output
var my_array = [],
    n = 5;
for (i = 0; i < n; i += 1) {
  my_array[i] = [];
}
console.log(my_array); // [[], [], [], [], []]

Upvotes: 1

Timur Bilalov
Timur Bilalov

Reputation: 3702

Line "Each element would get a reference to the same" related to Array.dim implementation from page 63:

// "Javascript: The Good Parts", page 63.
Array.dim = function (dimension, initial) {
 var a = [], i;
 for (i = 0; i < dimension; i += 1) {
 a[i] = initial;
 }
 return a;
};

Code at page 64 gives you an array of different pointers for array.

for (i = 0; i < n; i += 1) {
 my_array[i] = [];
}


// you can try to do this:
my_array[0].push(1);
my_array[1].push(2);

console.log(my_array[0]);
// [1]

console.log(my_array[1]);
// [2]

Upvotes: 1

Dan Prince
Dan Prince

Reputation: 29999

This loop does get a new reference each time. Run it, mutate one of the arrays and you'll see that only one changes.

The problem is much more likely to be with the Array.dim method. I would imagine that it's implemented something like this:

Array.dim = function(n, init) {
  var arr = [];
  var i;

  for (i = 0; i < n; i += 1) {
    arr[i] = init;
  }

  return arr;
}

Using the literal array syntax create a new reference to an array, but this method uses the same reference to populate each value of the resulting array.

It might be easiest to compare the two this way.

var init = [];
for (i = 0; i < n; i += 1) {
  arr[i] = init;
}

The first approach creates one array then uses it to populate each element.

for (i = 0; i < n; i += 1) {
  arr[i] = [];
}

The second approach creates a new reference for each iteration of the loop.

Upvotes: 1

Related Questions