我对setInterval有一个问题,我无法弄清楚。
我知道" (...)当从对象内部调用setInterval或timeout时,范围存在问题,但仍然无法绕过它。
我试图把我的东西放在一个匿名函数中,它不会工作。
这基本上是我的问题,简化为骨干:
function Scenario(){
var ships = [];
this.ini = function(){
for (var i = 0; i < ships.length; i++){
timeoutID1 = setTimeout(ships[i].ding, 1000);
timeoutID2 = setTimeout(ships[i].bing, 1000);
}
}
this.setShips = function(){
var ship = new Ship("ship");
ships.push(ship);
}
function Ship(name){
this.name = name;
this.ding = function(){
intervalID1 = setInterval(function(){
console.log("ding");
}, 500)
}
this.bing = function(){
var _this = this;
intervalID2 = setInterval(function(){
console.log(_this.name);
}, 500)
}
}
this.setShips();
}
var scenario = new Scenario();
scenario.ini();
http://jsfiddle.net/ancientsion/xkwsn7xd/
基本上,console.log(&#34; ding&#34;)有效, console.log(_this.name)不是。
为什么?
答案 0 :(得分:2)
这是你的问题简化为裸骨:
var ship = {
name: 'Sheep',
ding: function() {
console.log(this.name);
}
}
setTimeout(ship.ding, 1000); // doesn't work correctly
可能有助于看到另一个例子来理解为什么上述方法不起作用:
var ding = ship.ding;
ding(); // doesn't work either
在JavaScript中this
取决于您如何调用您的函数。 ship.ding()
会将this
设置为sheep
对象。仅ding()
次调用会将this
设置为window
对象。
您可以使用.bind()
方法将函数绑定到所需的对象。 (Function.prototype.bind())
var ding = ship.ding.bind(ship);
ding(); // works
ding
现在永久绑定到sheep
对象。您可以使用与setTimeout
完全相同的方法:
setTimeout(ship.ding.bind(ship), 1000);
答案 1 :(得分:0)
您应该在_this
函数中定义值Ship
:
function Ship(name){
this.name = name;
this.ding = function(){
intervalID1 = setInterval(function(){
console.log("ding");
}, 500)
}
var _this = this;
this.bing = function(){
intervalID2 = setInterval(function(){
console.log(_this.name);
}, 500)
}
}
答案 2 :(得分:0)
从bing函数中提升_this。
你应该_this = this,
this.bing = function() {
intervalID2 = setInterval(function(){
console.log(_this.name);
}, 500)
}
Javascript是必不可少的,因此您需要仔细遵循执行路径。在函数Ship中,这指向Ship对象,在函数bing中,它指向全局范围(窗口)。您需要保存对此的引用,以便您可以在这些类型的函数中引用它。
答案 3 :(得分:0)
当setTimeout()
到处调用你的方法时,它只能看到函数,而不是调用上下文(即绑定它的对象);很像这样:
var bing = ships[i].bing;
bing(); // inside bing(), this == window
基本上,您需要为setTimeout()
提供预先接线的方法调用:
var bound_bing = ships[i].bing.bind(ships[i]);
timeoutID2 = setTimeout(bound_bing, 1000);
&#34;魔法&#34;与.bind()
一起发生,因为它返回一个新功能,可以正确设置this
。
答案 4 :(得分:0)
你把ships[i].bing
放在setTimeout中,结果是bing的调用者不是ship [i]而是全局的,所以_this
实际指向全局。