2012-09-19 55 views
0

我正在使用JavaScript编写倒数计时器。相当基本。在时间方面只使用setInterval。我使用存储函数和变量的原型方法编写它,所以我可以创建一个“类”。Javascript“Class”via Prototypes - 变量未定义

我以这种方式调用代码。

function testTimer() { 
    var newTimer = new CDTimer($("#voteTimer"),30,""); 
    newTimer.start(); 
} 

当下面代码运行,console.log正在打印undefinedNaN

function CDTimer (target, duration, callback) { 
    this.target = target; 
    this.duration = duration; 
    this.callback = callback; 
} 

CDTimer.prototype.start = function() { 
    this.start = new Date().getTime(); 
    this.interval = setInterval(this.update, 1000); 
} 

CDTimer.prototype.update = function() { 
    console.log(this.duration, this.start); 
    this.elapsed = this.duration - (new Date().getTime() - this.start)/1000 

    if (this.elapsed < 0) { 
      clearInterval(this.interval); 
      this.callback(); 
    } 
    else { 
     console.log(this.elapsed); 
     $(this.target).text(this.elapsed); 
    } 
} 

CDTimer.prototype.stop = function() { 
    clearInterval(this.interval); 
} 

我一定错过了一些愚蠢的东西。我的变量及其价值发生了什么?

感谢您的洞察力。

+1

你期望'this'指什么?你还没有用你的构造函数创建任何对象。 –

回答

4

setInterval调用的函数提供了一个this这是窗口,而不是定时器。该MDN提供a detailed explanation

CDTimer.prototype.start = function() { 
    this.start = new Date().getTime(); 
    var _this = this; 
    this.interval = setInterval(function(){_this.update()}, 1000); 
} 

注:

你可以做到这一点。

编辑如下评论:如果你不想创建启动功能一个新的变量,你可以这样做:

CDTimer.prototype.start = function() { 
    this.start = new Date().getTime(); 
    this.interval = setInterval(function(_this){_this.update()}, 1000, this); 
} 

但我不知道可读性被这一举动的改进变量的创建,它与IE不兼容(如果你不打补丁,请参阅MDN的解决方案)。

+0

这正是答案。我现在看到你指出的问题。 'this'不是指'CDTimer',因为它在'setInterval'的'function()'范围内。正确?另外,感谢将我与MDN联系起来,我不知道它存在。 – Morrowind789

+0

我想知道,你可以通过将自己的引用传递给'function()'来跳过创建一个变量。像'function(this){...}'? – Morrowind789

+0

新浏览器的解决方案是创建[绑定](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/bind)函数。但我不推荐它,它不是很轻。 –