1
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は関数ではありません

何か案は?

ありがとう

4

4 に答える 4

2

文字列はオブジェクトのコンテキストで評価されないため、文字列がthis何をしていると思うかを参照しません。

文字列引数をに渡してはなりませんsetTimeout。代わりに、の保存されたコピーを使用してメソッドを呼び出す無名関数を渡す必要がありますthis

例えば:

var self = this;
setTimeout(function() { self.updateTime(); }, 1000);

のコールバックもオブジェクトのコンテキストで評価されないselfため、変数が必要です。setTimeout

于 2010-04-09T01:47:55.333 に答える
1

試す

var me = this;
setTimeout(function() { me.updateTime() }, 1000);
于 2010-04-09T01:47:21.233 に答える
1

もっとエレガントな方法はありますか?

はい、ECMAScript第5版では:

setTimeout(this.updateTime.bind(this), 1000);

ただし、すべてのブラウザーがFifth Editionをサポートするまで(まだ長い間サポートされていません)、フォールバックとして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ないdiffvarください。そうしないと、偶発的なグローバルが発生し、ひどいデバッグの心痛を引き起こす可能性があります。

于 2010-04-09T10:01:02.393 に答える
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);
  };

}
于 2010-04-09T01:48:37.880 に答える