function Timer() {
this.initialTime = 0;
this.timeStart = null;
this.getTotalTime = function() {
timeEnd = new Date();
diff = timeEnd.getTime() - this.timeStart.getTime();
return diff+this.initialTime;
};
this.formatTime = function() {
interval = new Date(this.getTotalTime());
return interval.getHours() + ":" + interval.getMinutes() + ":" + interval.getSeconds();
};
this.start = function() {
this.timeStart = new Date();
setTimeout("this.updateTime()", 1000);
};
this.updateTime = function() {
alert(this.formatTime());
setTimeout("this.updateTime()", 1000);
};
}
timer = new Timer();
timer.start();
我收到错误:
this.updateTime不是函数
有什么想法吗?
由于
答案 0 :(得分:2)
您的字符串不会在对象的上下文中进行评估,因此this
不会引用您的想法。
您不应该将字符串参数传递给setTimeout
。相反,您应该传递一个匿名函数,该函数使用保存的this
副本调用您的方法。
例如:
var self = this;
setTimeout(function() { self.updateTime(); }, 1000);
self
变量是必要的,因为setTimeout
的回调也不会在对象的上下文中进行评估。
答案 1 :(得分:1)
试
var me = this;
setTimeout(function() { me.updateTime() }, 1000);
答案 2 :(得分:1)
有更优雅的方式吗?
是的,在ECMAScript第五版中:
setTimeout(this.updateTime.bind(this), 1000);
但是,在所有浏览器都支持第五版(它们尚未进行长期测量)之前,您应该将自己的Function.bind实现添加为回退。例如:
// Add ECMA262-5 method binding if not supported natively
//
if (!('bind' in Function.prototype)) {
Function.prototype.bind= function(owner) {
var that= this;
if (arguments.length<=1) {
return function() {
return that.apply(owner, arguments);
};
} else {
var args= Array.prototype.slice.call(arguments, 1);
return function() {
return that.apply(owner, arguments.length===0? args : args.concat(Array.prototype.slice.call(arguments)));
};
}
};
}
您可能还希望使用setInterval
来避免重复的setTimeout
来电。最后,你应该记得将所有变量(timeEnd
,diff
等)声明为var
,否则你会得到偶然的全局变量,这会导致你可怕的调试心痛。 / p>
答案 3 :(得分:0)
如果您向setTimeout
提供字符串,则此字符串将按字面意思执行。问题是,它会在Timer
对象之外的全局上下文中执行,因此this
意味着完全不同的东西。
只需传递函数本身:
function Timer() {
var self = this; // make reference to this that won't change with context
this.updateTime = function() {
alert(self.formatTime());
setTimeout(self.updateTime, 1000);
};
}