1

What's the right way to do...

var array1 = []
var array2 = []

function doIt(arg){
    var myArray;

    if(arg == 1){
        myArray = array1
    }else if(arg == 2){
        myArray = array2
    }

    myArray.push('test');

}

doIt(1); //array1 should now be ['test'] but it's empty
userBG
  • 6,860
  • 10
  • 31
  • 39
  • What exactly do you mean by "it's empty"? You are missing some semi-colons, btw. – mechanical_meat Feb 27 '12 at 00:21
  • @AdamBernier: Doesn't JavaScript insert helpful automatic semicolons to make the programmer's life easier? Also, I assume that by "empty" the OP means that `array1` contains no elements (which is because `myArray = array` makes a *copy* of the array). – Kerrek SB Feb 27 '12 at 00:23
  • @Kerrek SB: you're probably right; some development environments likely auto-insert semi-colons. Regarding your second point: arrays are objects and are passed by reference. – mechanical_meat Feb 27 '12 at 00:27
  • @AdamBernier: No, I mean that the semicolons are implicit. You don't have to write them at all in certain circumstances. Good point about objects. – Kerrek SB Feb 27 '12 at 00:29
  • Hm, maybe they're really not necessary then, thanks. JSLint complained about them not being there. – mechanical_meat Feb 27 '12 at 00:31
  • @AdamBernier: They can produce very fiendish bugs, because they can get inserted in very unexpected places, so JSLint is definitely right to complain. – Kerrek SB Feb 27 '12 at 00:37
  • @AdamBernier: JavaScript has "automatic semicolon insertion", some people such as Brendan Eich, have criticized JSLint for complaining about semicolons. – Jesse Good Feb 27 '12 at 00:40
  • 1
    Javascript does not pass by reference. Like Java, objects are hidden behind references, and they are passed by value – newacct Feb 27 '12 at 00:44
  • @Kerrek SB - Semicolons don't get inserted in unexpected places, they get inserted according to a strict set of rules. (But I still prefer to explictly include them all myself.) – nnnnnn Feb 27 '12 at 00:47
  • 1
    @ofko - I see nothing wrong with the code in the question except that you'd get an error if you called your function with a value other than 1 or 2 (in which case it would try to do `undefined.push()`). But for a value of 1 it should work as you expect. Is there any other code not shown that could affect it? – nnnnnn Feb 27 '12 at 00:56
  • Yes, there must be other code somewhere in my script that is affecting it. I need to analyse it and follow up later. Asked this question at the wrong time I guess, have to be away for a while. Thank you all for your great feedback. – userBG Feb 27 '12 at 01:02

3 Answers3

2

Aside from four minor syntactic blemishes, your code is OK: http://jsfiddle.net/hk9Md/

var array1 = []; // <-- added semi-colon
var array2 = []; // <-- added semi-colon

function doIt(arg){
    var myArray;

    if (arg == 1) {
        myArray = array1; // <-- added semi-colon
    } else if (arg == 2) {
        myArray = array2; // <-- added semi-colon
    }
    myArray.push('test');
}
doIt(1);
alert(array1[0]); // produces 'test' 
mechanical_meat
  • 163,903
  • 24
  • 228
  • 223
  • 1
    Those "missing" semicolons are all optional. I prefer to include them as a matter of style, but this particular code will work exactly the same with or without them. (I acknowledge that there _are_ cases where inclusion of a semicolon matters, but this is not such a case.) – nnnnnn Feb 27 '12 at 00:51
  • @nnnnnn: that's interesting behavior, thanks. And thanks to Kerrek SB for mentioning the same in other comments. – mechanical_meat Feb 27 '12 at 01:18
  • 1
    I found out that my code was passing the wrong value for `arg` and that was the problem. I hope this will be helpful for someone anyway. – userBG Feb 27 '12 at 02:11
0

Why not:

var myArray = arg == 1? array1 : array2;

If there are more than two choices, you might try:

var source = {
  '1': array1,
  '2': array2,
  '3': array3,
  ...
}

or zero–indexed:

var source = [ ,array1, array2, array3, ...];

then:

function doIt(arg) {
  var myArray = source[arg];
  ...
}  

or even:

var doIt = (function() {
  var source = {
    '1': array1,
    '2': array2,
    '3': array3,
    ...
  }
  return function (arg) {
    var myArray = source[arg];
  }
}());

Fill yer boots. :-)

RobG
  • 142,382
  • 31
  • 172
  • 209
  • OK, they're all other ways of implementing what is in the question, but why doesn't the original code work as is? – nnnnnn Feb 27 '12 at 00:58
0

Arguably, the "right" way to do this is not to write functions with side effects. You could write the function so that it returns a modified copy of the array:

var array1 = [1, 2, 3],
    array2 = [4, 5, 6],
    x = getUserInput(),
    result = doIt(1, x == 1 ? array1 : array2);

function doIt(arg, original_array){
  var copy = [].concat(original_array);
  // ...
  return copy;
}

Sometimes it's unavoidable, but programs get much harder to debug when local functions change global state.

Brandan
  • 14,735
  • 3
  • 56
  • 71