1

I have an array ele, and I want to populate another array arr with copies of ele, and then return the populated array. The JavaScript function I have is:

function foo(n) {
    var arr = new Array(n);
    var ele = [0,1];

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

for e.g. foo(3), the output I want is [[0,1],[0,1],[0,1]], but I instead get the output: [#1=[0, 1], #1#, #1#] (using Firefox's Web Console). When I instead populate arr with [0,1] directly, as in

function fooNew(n) {
    var arr = new Array(n);

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

I get the correct output for fooNew(3): [[0,1],[0,1],[0,1]]. Why does my original function foo not give the same output as fooNew? That is: why can't I populate arr by assigning ele to arr[i], and instead have to populate it by assigning the content of ele directly to arr[i], to get the output I want?

======

Update: in light of Felix Kling's helpful answer, and after some googling, I found that by using slice(0), you can place a copy of ele into arr[i] rather than a reference to it. So the following modification of foo will give the desired output:

function foo(n) {
    var arr = new Array(n);
    var ele = [0,1];

    for(var i=0;i<n;i++) {
        arr[i] = ele.slice(0);
    }

    return arr;
}
2
  • 2
    Just as a comment, I see it correctly both on Firefox/Firebug and Chrome. Just be careful, on the first example, you're assigning a reference to the SAME ele array to all the positions on arr. So if you do something like x = foo(3); x[0].push(2);, now all the arrays on x have three elements (Because they're actually the same array) Commented Feb 28, 2012 at 20:32
  • Works for me. In Chrome, Firefox (Firebug) & Node.js. As @julio.olvr said be careful when assigning ele. Arrays, like objects {} are pointers to collections. So if var x = [1,2,3] and then var y = x and then y[0] = 9 you will end up with an x of [9,2,3]. Commented Feb 28, 2012 at 20:34

1 Answer 1

4

Actually, Firebug's output is quite helpful in this situation . It tells you that every element of your resulting array references the same array:

  [#1=[0, 1], #1#, #1#]
//  ^----------^----^  

#1 (or #1#) is a placeholder for the array [0, 1], indicating a reference.

It is still an array of arrays, it's just differently represented by Firebug.

I'm not sure if this is what you want though. For example, if you modify the first element of the first array:

result[0][0] = 5;

the result would be

[[5,1], [5,1], [5,1]]

I assume you want the arrays to be independent from each other, therefore you have to assign a new array each time. This is what you do in the second case.


†: But it is also a reminder that one should not always believe everything one sees. The state of an object (for example) can be quite different from how tools represent it. Here is an article about such a case (sorry for self promotion), the issue is fixed in Firebug, but not in Chrome (afaik).

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks! I didn't know what to make of the notation "#1#" (google won't let you query such strings, it seems), but this makes sense.
I don't normally use Firebug, but that output is really clever and useful. Thanks for explaining!
@user1238742: You're welcome :) If it helped you, please mark this answer as accepted by clicking the tick outline next to it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.