我决定制作一个简单的画布游戏,并在延迟后将布尔变量更改为false
(来自true
)。我做了一个看起来像这样的简单函数:
var someVariable = true;
function changeBoolean(){
someVariable = false;
}
setTimeout(changeBoolean, 1000);
。 。 。它完美无缺。但是我的游戏越来越大,我不想为每个变量创建额外的函数,所以我想出了一个方法来做到这一点:
var someVariable = true;
function changeBoolean(argument) {
argument = false;
}
setTimeout(changeBoolean(someVariable),1000);
。 。 。它不起作用。有人可以告诉我我做错了什么吗?谢谢你的帮助。
答案 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
被设置为true
或false
,但它不知道外面哪个变量具有该值,因此不能改变其值。
一种解决方案可能是将变量存储在对象中,只需告诉changeBoolean
要更改的键:
var variables = {
someVariable: true
};
function changeBoolean(argument) {
variables[argument] = false;
}
setTimeout(function(){
changeBoolean('someVariable');
},1000);