似乎我无法在this
函数中使用setInerval
。这是为什么?什么是优雅的解决方案?
<html>
<script>
var something = function(tMessage){
this.message = tMessage;
};
something.prototype = {
start : function(counter){
document.getElementById('result').innerHTML += this.message + "+++<br />";
var looper = setInterval(
function(){
// This is printing "undefined"
document.getElementById('result').innerHTML += this.message + "<br />";
if(!counter--)
clearInterval(looper);
},
20
);
}
};
window.onload = function(){
var e = new something("hi");
e.start(2);
}
</script>
<body>
<div id="result"></div>
</body>
</html>
感谢您的回答!!但是,任何人都可以解释发送参数和设置和额外变量之间的区别吗?有任何记忆问题吗?
答案 0 :(得分:6)
这里的问题是,当调用函数时,this
引用全局对象。要保留当前范围,可以进行闭包:
var looper = setInterval(
(function(scope){
return function(){
// This will no longer be printing "undefined"
document.getElementById('result').innerHTML += scope.message + "<br />";
if(!counter--)
clearInterval(looper);
};
})(this),
20
);
我会引导您找到这个优秀的答案,而不是手工操作并尝试解释闭包({我3}}
答案 1 :(得分:2)
您不能使用this
因为您处于新的功能块中。我总是创建一个局部变量(我确信有更好的方法):
var c = this;
setInterval(function(
c.variable = 1;
), 100);
答案 2 :(得分:1)
因为问题被标记为[prototypejs],但没有一个答案使用Prototype,我决定写一个真正使用Prototype(jsfiddle)的答案。
var Something = Class.create({
initialize: function(tMessage) {
this.message = tMessage;
},
start: function(counter) {
this.counter = counter;
$("result").innerHTML += this.message + "+++<br />";
this.looper = setInterval(this.addMessage.bind(this), 20);
},
addMessage: function() {
$("result").innerHTML += this.message + "<br />";
if (!this.counter--) {
clearInterval(this.looper);
}
}
});
document.observe("dom:loaded", function() {
var e = new Something("hi");
e.start(2);
});
document.getElementById()
。window.onload
问题的关键在于功能的执行上下文。无论您在何处使用this
,它都只指向当前的执行上下文。当您调用someObject.someFunction()
时,someFunction()
将在someObject
的上下文中执行,this
内的someFunction()
将指向someObject
。
但您可以进行作业someOtherObject.someFunction = someObject.someFunction
,然后在someOtherObject.someFunction()
this
中指向someOtherObject
。
此外,您可以将函数的引用传递给另一个函数,就像在setInterval()
中一样,然后执行上下文将由setInterval()
定义(实际上它将是全局上下文,即{{1} })。
为了将执行上下文绑定到函数(预定义上下文,覆盖调用者的上下文),您需要使用this===window
方法。它返回新函数,无论运行时的上下文是什么,它都将使用您想要的上下文调用原始函数。
答案 3 :(得分:0)
添加
var self = this;
在调用setInterval之前,使用self而不是this到set * interval
中定义的函数