我在一个控制玩家重生的函数内部定义了一个setTimeout(我正在创建一个游戏):
var player = {
...
death:(function() {
this.alive = false;
Console.log("death!");
var timer3 = setTimeout((function() {
this.alive = true;
Console.log("alive!");
}),3000);
}),
...
}
Run Code Online (Sandbox Code Playgroud)
当它执行时,我在控制台中读到"死!" 3秒后"活着!".但是,alive永远不会真正设置为true,因为如果我player.alive在控制台中写入,它将返回false.为什么我能看到"活着!" 但变量永远不会回归真?
zos*_*tay 31
你必须要小心this.您需要将this外部范围中的您分配给变量.this关键字始终引用this当前范围的关键字,当您将内容包装时,该关键字会随时更改function() { ... }.
var thing = this;
thing.alive = false;
Console.log("death!");
var timer3 = setTimeout((function() {
thing.alive = true;
Console.log("alive!");
}),3000);
Run Code Online (Sandbox Code Playgroud)
这应该会给你更好的成功.
小智 20
这是因为this在setTimeout处理程序中引用的window,可能this与处理程序外部引用的值不同.
你可以缓存外部值,并在里面使用它......
var self = this;
var timer3 = setTimeout((function() {
self.alive = true;
Console.log("alive!");
}),3000);
Run Code Online (Sandbox Code Playgroud)
......或者你可以使用ES5 Function.prototype.bind......
var timer3 = setTimeout((function() {
this.alive = true;
Console.log("alive!");
}.bind(this)),3000);
Run Code Online (Sandbox Code Playgroud)
...但是如果你支持遗留实现,你需要添加一个垫片Function.prototype.
......或者如果你在ES6环境中工作......
var timer3 = setTimeout(()=>{
this.alive = true;
Console.log("alive!");
},3000);
Run Code Online (Sandbox Code Playgroud)
为了防止任何人读到这个,新的javascript语法允许您使用"bind"将范围绑定到函数:
window.setTimeout(this.doSomething.bind(this), 1000);
Run Code Online (Sandbox Code Playgroud)
可能是因为this超时回调中没有保留.尝试:
var that = this;
...
var timer3 = setTimeout(function() {
that.alive = true;
...
Run Code Online (Sandbox Code Playgroud)
更新(2017) - 或使用lambda函数,它将隐式捕获this:
var timer3 = setTimeout(() => {
this.alive = true;
...
Run Code Online (Sandbox Code Playgroud)
使用 ES6 函数语法,'this' 的作用域不会在 setTimeout 内改变:
var timer3 = setTimeout((() => {
this.alive = true;
console.log("alive!");
}), 3000);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
33792 次 |
| 最近记录: |