setTimeout范围问题
setTimeout scope issue
我在一个控制玩家重生的函数中定义了一个setTimeout(我正在创建一个游戏):
var player = {
...
death:(function() {
this.alive = false;
Console.log("death!");
var timer3 = setTimeout((function() {
this.alive = true;
Console.log("alive!");
}),3000);
}),
...
}
当它执行时,我在控制台中读到"死亡!",3秒钟后读到"活着!"。然而,alive
从未真正设置回true,因为如果我在控制台中写入player.alive
,它将返回false
。为什么我能看到"活着!",但变量从未设置为true?
您必须小心使用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);
这会给你带来更好的成功。
更新2019-10-09:最初的答案是正确的,但现在可以为最新版本的JavaScript提供另一个选项。您可以使用箭头函数来代替function
,该函数不会修改this
:
this.alive = false;
Console.log("death!");
var timer3 = setTimeout(() => {
this.alive = true;
Console.log("alive!");
}), 3000);
这是由ES6-forward支持的,我认为它是除IE(当然)之外的所有当前浏览器的一部分。如果你正在使用一个现代的框架通过Babel或其他什么来构建你的项目,这个框架应该确保它在任何地方都能像预期的那样工作。
这是因为setTimeout
处理程序中的this
引用的是window
,该值可能与处理程序外的this
引用的值不同。
您可以缓存外部值,并在内部使用它。。。
var self = this;
var timer3 = setTimeout((function() {
self.alive = true;
Console.log("alive!");
}),3000);
或者您可以使用ES5 Function.prototype.bind
。。。
var timer3 = setTimeout((function() {
this.alive = true;
Console.log("alive!");
}.bind(this)),3000);
不过,如果您支持遗留实现,则需要向Function.prototype
添加一个填充程序。
- MDN
Function.prototype.bind
补丁
或者如果你在ES6环境中工作。。。
var timer3 = setTimeout(()=>{
this.alive = true;
Console.log("alive!");
},3000);
因为CCD_ 19中没有CCD_ 18的结合。
为了防止有人读到这篇文章,新的javascript语法允许您使用"bind"将作用域绑定到函数:
window.setTimeout(this.doSomething.bind(this), 1000);
可能是因为this
没有保留在超时回调中。尝试:
var that = this;
...
var timer3 = setTimeout(function() {
that.alive = true;
...
Update(2017)-或使用lambda函数,该函数将隐式捕获this
:
var timer3 = setTimeout(() => {
this.alive = true;
...
使用ES6函数语法,"this"的范围在setTimeout:内不会更改
var timer3 = setTimeout((() => {
this.alive = true;
console.log("alive!");
}), 3000);
- setInterval游戏循环的范围问题
- Javascript innerHTML超出范围的问题
- AngularJs避免范围界定问题
- firefox中的Javascript事件范围问题
- AngularJS指令范围约束问题重复出现
- jQuery“this”范围问题
- 可以't在quizz页面范围问题上用最终分数更新变量
- JavaScript 函数变量范围问题
- 奇怪的可变范围问题
- JavaScript 中变量范围的问题
- 主干.js(具有 Require.js)变量/范围访问问题
- 递归承诺调用 - 内存范围变量问题
- JQuery 范围滑块步进更改问题
- AngularJS中的范围问题
- 如何在 JavaScript for D3.js 中解决这样的范围问题
- 我可以设置这个吗'某事'在该服务中动态创建的嵌套对象中的服务?(可能是范围问题)
- Highcharts列范围工具提示问题
- 在函数中提示未定义返回.(问题)范围
- 访问Javascript's变量:涉及Javascript, JQuery和PHP/MySQL的问题&范围
- JavaScript 闭包问题..范围