11

I have an array of colors that I want the option to reverse. I have a toggle function that basically colors elements based on the array. If I throw a reverse variable then it reverses, but it reverses the global variable instead of the local variable.

var inc_colors = ['#000','#333','#888']; //global inc_colors

function toggleLegendColors(reverse){
  var reverse = reverse || false;
  var colors = inc_colors; //local colors
  if(reverse) colors.reverse(); //reverses inc_colors array as well as colors
  ...
}

How can I get the reversed global array without changing the global array?

3

5 Answers 5

14

Since nobody has really explained why you were having a problem, I'll add that to the mix.

When you assign an array or an object in javascript to a variable, it assigns a reference to that array/object. It does not make a copy of the array/object. So, then you would have two variables that both point at the same array/object and modifying either one will affect the other (since they both point to the same underlying piece of data).

So, when you had this:

var inc_colors = ['#000','#333','#888']; //global inc_colors
var colors = inc_colors; //local colors

All you have now is two variables that both point to the exact same piece of data. Modify either one and the same result will show via the other variable because they point to the same underlying data.

If you want to make a copy, then have to explicitly make a copy (javascript doesn't do it for you automatically). For an array, the simplest way to make a shallow copy is like this:

var newColors = Array.prototype.slice.call(inc_colors);

So, in your exact code, you could apply that copy like this:

var inc_colors = ['#000','#333','#888']; //global inc_colors

function toggleLegendColors(reverse){
  var reverse = reverse || false;
  var colors = Array.prototype.slice.call(inc_colors);  //local copy of the colors array
  if(reverse) colors.reverse(); //reverses inc_colors array as well as colors
  ...
}
Sign up to request clarification or add additional context in comments.

4 Comments

Why does that happen to arrays and not other variable types?
@bozdoz - it happens to arrays and objects. Strings are immutable so they can never be changed (a new string object is created whenever the string is modified) so you can't have a constant reference to a string that gets modified. The other variable types (boolean, number, etc...) are just simple types and when they are assigned they are copied. As to why it's this way, that would need to be explained by the designers of the language.
Why does it matter why they were having the problem?
@daniella - Understanding how assignment of objects works in Javascript is fundamental to writing good code.
14

You can do this by using the es6 spread operator now too:

let colors = [ ...inc_colors ].reverse()

2 Comments

@RubenMartinezJr. using it for same reason. good use of spread operator.
This is really simple and efficient
11

Just make a copy of the array using Array.slice (safe way):

var colors = Array.prototype.slice.call(inc_colors);

9 Comments

what I meant is: are you sure you don't mean reverse.call()? :)
var colors = inc_colors.slice(); also will work, because it's an array
@ithcy: You want to copy the array before you reverse it, so that you are reversing the copy.
@Ian It is just a safe way. In case if inc_colors is not an array.
@Ian: You normally use Array.prototype.slice.call when the "array" isn't really an array, like a NodeList or arguments.
|
11

clean simple way that you may consider , but involves creating a new instance of the array is

var arr_reverse=arr.slice(0).reverse();

1 Comment

0 is not required (default)
1

Simplistic solution:

var inc_colors = ['#000','#333','#888']; //global inc_colors

function toggleLegendColors(reverse) {
  var colors = (inc_colors instanceof Array) ? inc_colors : [];
  colors = (!reverse) ? inc_colors.slice() : inc_colors.slice().reverse();
  // ...
}

1 Comment

Do you need the var for inc_colors inside the function? If you take it out, it will keep inc_colors global, in case it was never defined. Not too important, just didn't know if there was a reason for the var :)

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.