24

setTimeoutjavascript オブジェクトで使用できないのはなぜですか?

Message = function () {

    ...
    ...        

    this.messageFactory = ...
    this.feedbackTag = document.getElementById('feedbackMessages');

    this.addInfo = function (message) {
        var info = this.messageFactory.createInfo(message); // create a div
        this.feedbackTag.appendChild(info);

        setTimeout('this.feedbackTag.removeChild(info)', 5000);
        // why in here, it complain this.feedbacktag is undefined ??????

    };
}

スティーブのソリューションに感謝します。コードが以下の場合に機能するようになりました...前の「this」は実際にはsetTimeOut内の関数を指していたため、メッセージを検索できません。

Message = function () {

    ...
    ...        

    this.messageFactory = ...
    this.feedbackTag = document.getElementById('feedbackMessages');

    this.addInfo = function (message) {
        var info = this.messageFactory.createInfo(message); // create a div
        this.feedbackTag.appendChild(info);

        var _this = this;
        setTimeout(function() { _this.feedbackTag.removeChild(info); }, 5000);

    };
}

しかし、これを行うとうまくいかないのはなぜですか:

Message = function () {

    ...
    ...        

    this.messageFactory = ...
    this.feedbackTag = document.getElementById('feedbackMessages');
    // public function
    this.addInfo = function (message) {
        var info = this.messageFactory.createInfo(message); // create a div
        this.feedbackTag.appendChild(info);

        delayRemove(info);

    };
    // private function
    function delayRemove(obj) {
        var _this = this;
        setTimeout(function() { _this.feedbackTag.removeChild(info); }, 5000);
    }
}
4

3 に答える 3

84

この行を置き換えてみてください:

setTimeout('this.feedbackTag.removeChild(info)', 5000);

これらの2行で:

var _this = this;
setTimeout(function() { _this.feedbackTag.removeChild(info); }, 5000);

ノート:

setTimeoutこれが呼び出すので、決して文字列を渡さないevalでください (必要な場合にのみ使用してください)。代わりにsetTimeout、関数参照を渡します (これは無名関数にすることができます)。

this最後に、キーワードが指していると思われるものを指していることを常に確認してください ( http://www.alistapart.com/articles/getoutbindingsituationsを参照)。

質問 2 への対処:

通常の関数では、宣言されている場所に関係なく、オブジェクトにthis設定されていると思います。windowそのため、コードを別の関数に移動しても問題は解決しません。

于 2009-07-09T03:39:06.853 に答える
9

きちんとした方法は、タイムアウトで呼び出される関数への引数としてこれを渡すことです。

function delayRemove(obj) {
  setTimeout(function(_this) {
      _this.feedbackTag.removeChild(obj);
    }, 5000, this);
}

objがスコープ内にあることを確認するために、実際にはobjも引数として渡す必要があります(パラメーターの数は無制限です)。

function delayRemove(obj) {
  setTimeout(function(_this, removeObj) {
      _this.feedbackTag.removeChild(removeObj);
    }, 5000, this, obj);
}

HTML5とNode.jsはsetTimeout、コールバック関数に渡されるパラメーターを受け入れるように関数を拡張しました。次のメソッドシグネチャがあります。

setTimeout(callback, delay, [param1, param2, ...])

setTimeout 実際にはJavaScript機能ではないため、結果はブラウザによって異なる場合があります。サポートの具体的な詳細は見つかりませんでしたが、これはHTML5仕様に含まれています。

于 2011-03-16T20:40:22.007 に答える
2

最後の質問に答えるには、「これを実行してもうまくいかないのはなぜですか」:

Message = function () {

...
...        

this.messageFactory = ...
this.feedbackTag = document.getElementById('feedbackMessages');
// public function
this.addInfo = function (message) {
    var info = this.messageFactory.createInfo(message); // create a div
    this.feedbackTag.appendChild(info);

    delayRemove(info);

};
// private function
function delayRemove(obj) {
    var _this = this;
    setTimeout(function() { _this.feedbackTag.removeChild(info); }, 5000);
}}

info定義済み変数 ( ) の代わりに未定義変数 ( ) を渡しているため、機能していませんobj。修正された関数は次のとおりです。

function delayRemove(obj) {
var _this = this;
setTimeout(function() { _this.feedbackTag.removeChild(obj); }, 5000);}
于 2010-12-01T14:29:35.933 に答える