3

I've found a kind of estrange effect while I was using several related arrays. After break my mind looking for the error, finally I've found a solution. But I would like to know if any of you can explain me why is happening this.

My code was something like:

var closed =['closed', 'closed', ..., 'closed'];
sunday = closed;
...
saturday = closed;

After this if i do:

sunday[2] = 'open';

I get sunday[2] = 'open', monday[2] = 'open', tuesday[2] = 'open', ..., saturday[2] = 'open'. It's like all the variables were been 'glued' or linked because no mater which you change, all of them change in the same way.

I've fixed it in this way:

var closed1 =['closed', 'closed', ..., 'closed'];
...
var closed7 =['closed', 'closed', ..., 'closed'];
sunday = closed1;
...
saturday = closed7;

And now I get independent variables. But I don't like this solution, so I'd be grateful if someone knows the problem. I'm running JavaScript over Google Chrome.

Thanks

Oscar Parra
  • 185
  • 1
  • 10

3 Answers3

8

Arrays are Objects, and Objects are reference types.

Each variable sunday, monday, tuesday, etc... holds a reference to the same Array, so each variable is able to observe changes to that Array.


Looking at your code, I have a gut feeling that maybe you should be using an Object instead of an Array.

var closed = {
    sunday:    'closed',
    monday:    'open',
    tuesday:   'open',
    wednesday: 'open',
    thursday:  'open',
    friday:    'open',
    saturday:  'closed'
};

Just a hunch though. Thought I'd throw it out there.

I Hate Lazy
  • 47,415
  • 13
  • 86
  • 77
  • 2
    To underline the point: there is only 1 array with many references in the original version. – Phil H Oct 30 '12 at 15:33
4

The problem is that in JavaScript, object types (which includes arrays like closed in your example) are references to the actual object (related question). This means that if x is a variable and its value is of object type, y = x does not put a copy of x into y; it simply means that you can use both names to refer to the same object.

What you would actually want here is to create copies of closed ("clone" it). Since it's an array, you can easily do that with

sunday = closed.slice(0); // etc
Community
  • 1
  • 1
Jon
  • 428,835
  • 81
  • 738
  • 806
  • You can call slice without a parameter for the same effect. `sunday = closed.slice();` – Waxen Oct 30 '12 at 15:39
  • So, I've found other methods like: sunday = ([]).concat(closed); reading about 'deep copy', but I'm new at OOP and I don't have clear these concepts. I'll use slice() – Oscar Parra Oct 31 '12 at 10:03
1

To get copies instead of references to the original array, use slice:

var closed = ['closed', 'closed', ... ];
var sunday = closed.slice();
var monday = closed.slice();
Phil H
  • 19,928
  • 7
  • 68
  • 105