19

How come the following code is giving me a 0 instead of a 1? I want my function to change a variable declared outside the function but I do not want to specify the variable in the function declaration.

that = 0;

function go(input) {
    input++;
}

go(that);

console.log(that);
Emanegux
  • 1,092
  • 2
  • 20
  • 38
  • 1
    Offtopic: Always declare your variables with `var`. Or, if it's a global variable, you can also set them as a property of `window` (e.g. `window.that = 0`) – Oriol Aug 12 '13 at 02:42

5 Answers5

22

As answered by Oriol, it doesn't work because the variable is passed by value, so you're not changing the "that" variable. A workaround would be to pass the variable name :

that = 0;

function test(input) {
    window[input]++;
}

test("that");

console.log(that); // 1
Phil-R
  • 2,193
  • 18
  • 21
  • I was looking for a way to use window.input without meaning a variable called input declared outside the function – Emanegux Aug 12 '13 at 02:31
  • 1
    I think that's the closest you can go. The test function has no reference to any variable, it just gets it from the parameter. Your question said "I do not want to specify the variable". Otherwise, you'd have to use an object like others have described in their answers. – Phil-R Aug 12 '13 at 02:39
20

That's because you are passing the variable by value, not by reference.

In javascript, all variables are passed by value, except objects, which are passed by reference (well, in fact they are passed by value too but they are a reference, see below).

And you can't change that behaviour.

Edit: If you don't know what passing by value/reference means, you should read a tutorial. But here you have some examples:

  • Variable passed by value

    function foo(bar){
       console.log(bar); // 1
       bar++;
       console.log(bar); // 2
    }
    var mybar = 1;
    console.log(mybar); // 1
    foo(mybar);
    console.log(mybar); // 1
    
  • Variable passed by (value but used as a) reference

    function foo(bar){
       console.log(bar.a); // 'b'
       bar.a = 'c';
       console.log(bar.a); // 'c'
    }
    var mybar = {a:'b'};
    console.log(mybar.a); // 'b'
    foo(mybar);
    console.log(mybar.a); // 'c'
    

In your case

You can do

  • Make your variable a property of an object (in your case, since it's a global variable, use window) and pass the object (reference), so you can alter it

    window.that = 0;
    function go(obj) {
        obj.that++;
    }
    go(window);
    console.log(that); // 1
    
  • Use a return value

    var that = 0;
    function go(input) {
        return input++;
    }
    that = go(that);
    console.log(that); // 1
    

Note that you can't do

  • Convert your variable into an object

    var that = new Number(0); // Now it's an object number
    function go(input) {
        input++;
    }
    go(that);
    that *= 1; // Now it's a literal number
    console.log(that); // 0
    

    That's because objects are passed by value too, but they are a reference. That means that inside the function you can change the properties of the outer object (because it's a reference) but you can't change the entire object, because it's passed by value.

    See examples here: https://stackoverflow.com/a/3638034/1529630

Community
  • 1
  • 1
Oriol
  • 274,082
  • 63
  • 437
  • 513
3

This has to do with pointers, scope, passing variables by reference, and all that jazz.

If you really want to do this, you can pass an object in Javascript like this:

var that = {value: 0};
function go(input) {
    input.value++;
}
go(that);
console.log(that.value);

All we've done is made that an object which is by definition passed as a reference in Javascript. Then we just make sure we properly modify the object's attributes.

Matt Pavelle
  • 819
  • 5
  • 8
1

Your code

that = 0; //Global variable

function go(input) { //input is argument and is not passed by reference
    input++; //This just increments a local copy i.e 0
}

go(that); //Passed 0 

console.log(that);

Instead do this

that = 0;

function go() {
    that++;
}

go(); //Not passing any variable .. function can already see the gloabl "that" 

console.log(that); // This will print gloabl i.e. 1

woofmeow
  • 2,370
  • 16
  • 13
-4

Actually you could just add console.log(input) inside the function and it would work just fine.

Please correct me if i'm wrong. Hope i helped !!

I would be glad if somebody could explain why im wrong