Search code examples
javascriptfunctionglobal-variableslocal-variables

Using copies of global variables in functions


Consider I have a global variable called generatedPattern. I want to use it in a function animate(), but do not want to change its value. So I copy generatedPattern to a local var(say var patternToAnimate) in the function and then use patternToAnimate.

Will any change to patternToAnimate change generatedPattern? If so, how do I avoid this?

I.e., how do I use generatedPattern in a function locally without changing it globally?

Code

function animateGeneratedPattern() {

    var patternToAnimate = generatedPattern;

    function animateNextPattern(lightup) {
        if (!patternToAnimate|| patternToAnimate.length === 0) {
            return;
        }

        switch(patternToAnimate[0]) {
            case 1:
                animateRed();
                break;
            case 2:
                animateGreen();
                break;
            case 3:
                animateBlue();
                break;
             case 4:
                animateYellow();
                break;
        }

        if (lightup) {
            // Long delay before turning light off
            setTimeout(function() {
                animateNextPattern(false);
            }, 500);
        }
        else {
            patternToAnimate.splice(0, 1);
            // Small delay before turning on next light
            setTimeout(function() {
                animateNextPattern(true);
            }, 10);
        }
    }
    animateNextPattern(true);
}

When patternToAnimate gets spliced, so does generatedPattern.


Solution

  • If you use and alter generatedPattern somewhere else, well, it gets changed.

    If you want to use the values of genratedPattern in another function without modifying it, you indeed have to copy it. But beware, don't save it as a reference:

    var generatedPattern = [1, 2, 3];
    var patternToAnimate = generatedPattern;
    

    Here, patternToAnimate is a reference to generatedPattern. So when you modify patternToAnimate generatedPattern gets modified as well. As they are literally the same arrays.

    If you want to copy one array to another, use slice

    var generatedPattern = [1, 2, 3];
    var patternToAnimate = generatedPattern.slice();
    

    Now patternToAnimate is a new, copy of generatedPattern which can be modified without modifying the original array.

    Demo: https://jsfiddle.net/kx7f766w/1/