Tuniak
Tuniak

Reputation: 13

setTimeout is not working when I pass a parameter into the function

I've decided to make a simple canvas game and I to change a Boolean variable to false (from true) after delay. I've made a simple function that looks like this:

var someVariable = true;

function changeBoolean(){
    someVariable = false;
}

setTimeout(changeBoolean, 1000);

. . . and it works perfectly. But my game is getting bigger and I don't want to make extra functions for every variable, so I figured out a way to do it like this:

var someVariable = true;

function changeBoolean(argument) {
    argument = false;
}

setTimeout(changeBoolean(someVariable),1000);

. . . and it doesn't work. Can someone please tell me what I'm doing wrong? Thanks for help.

Upvotes: 0

Views: 1109

Answers (2)

Travis J
Travis J

Reputation: 82267

The problem is that JavaScript is pass by value, not by reference. This means that by changing argument, you are not changing someVariable.

From a more technical perspective, JavaScript uses something called Variable Environment (think of a local scope) for variables in functions. The values from this environment will not be persisted to the Lexical Environment (think more globally scoped) once the scope closes.

JavaScript uses as stack of Execution ContextsECMA in order to maintain its scoping, and if you would like more information about the structure of scoping that is a good place to start.


Scoping aside, as @RocketHazmat points out, in order for setTimeout to work, it needs to be passed a function to call. Your example code is passing the result of a function call, and there is no return value, so in essence this is just setTimeout(undefined,1000) which will not work.

Please see Rocket's explanation in their answer for a suggestion to call the setTimeout, it is essentially what I would place here.

Upvotes: 2

gen_Eric
gen_Eric

Reputation: 227220

You need to pass setTimeout a function to call. That's what you are doing in the first example, you are passing it changeBoolean which is a function.

In the second example, you are calling changeBoolean(someVariable), then passing its return value - undefined - to setTimeout.

You can passing an anonymous function instead:

setTimeout(function(){
    changeBoolean(someVariable);
},1000);

This won't actually work though as someVariable will be passed by value, so all changeBoolean will see is argument being set true or false, but it won't know which variable outside had that value, so it can't change its value.

One solution could be to store your variable in an object, and just tell changeBoolean what key to change:

var variables = {
    someVariable: true
};

function changeBoolean(argument) {
    variables[argument] = false;
}

setTimeout(function(){
    changeBoolean('someVariable');
},1000);

Upvotes: 3

Related Questions