将参数传递给函数时,setTimeout不起作用

时间:2017-04-11 18:33:53

标签: javascript

我决定制作一个简单的画布游戏,并在延迟后将布尔变量更改为false(来自true)。我做了一个看起来像这样的简单函数:

var someVariable = true;

function changeBoolean(){
    someVariable = false;
}

setTimeout(changeBoolean, 1000);

。 。 。它完美无缺。但是我的游戏越来越大,我不想为每个变量创建额外的函数,所以我想出了一个方法来做到这一点:

var someVariable = true;

function changeBoolean(argument) {
    argument = false;
}

setTimeout(changeBoolean(someVariable),1000);

。 。 。它不起作用。有人可以告诉我我做错了什么吗?谢谢你的帮助。

2 个答案:

答案 0 :(得分:2)

问题在于JavaScript是按值传递的,而不是通过引用传递的。这意味着,通过更改argument,您不会更改someVariable

从更技术的角度来看,JavaScript在函数中使用称为变量环境(想到局部范围)的变量。一旦范围关闭,此环境中的值将不会持久保存到词法环境(更多地考虑全局范围)。

JavaScript使用 Execution ContextsECMA 的堆栈来维护其范围,如果您想了解有关范围结构的更多信息,那么这是一个很好的起点。

除了@RocketHazmat points out之外,为了setTimeout工作,需要传递一个函数来调用。你的示例代码传递了一个函数调用的结果,并且没有返回值,所以实际上这只是setTimeout(undefined,1000),它不起作用。

请参阅Rocket's explanation in their answer以获取调用setTimeout的建议,这基本上就是我要放在这里。

答案 1 :(得分:2)

您需要通过setTimeout 功能来致电。这就是你在第一个例子中所做的,你传递的是changeBoolean这是一个函数。

在第二个示例中,您调用 changeBoolean(someVariable),然后将其返回值 - undefined - 传递给setTimeout

您可以改为传递匿名函数

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

虽然someVariable会按值传递,但实际上并不起作用,因此所有changeBoolean都会看到argument被设置为truefalse ,但它不知道外面哪个变量具有该值,因此不能改变其值。

一种解决方案可能是将变量存储在对象中,只需告诉changeBoolean要更改的

var variables = {
    someVariable: true
};

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

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