簡體   English   中英

為什么在這種情況下“這”不是應該的?

[英]Why is 'this' not what it should be in this context?

我有一個在畫布上使用的函數,我試圖清除一個用.animate函數調用的間隔,但是當我調用.unbind(); 它仍然記錄未定義的日志,何時應該記錄超時,我不確定為什么它不起作用,也許你們可以幫忙

function Character(model, srcX, srcY, srcW, srcH, destX, destY, destW, destH) {
    this.model  = model;
    this.srcX  = srcX;
    this.srcY  = srcY;
    this.srcW  = srcW;
    this.srcH  = srcH;
    this.destX = destX;
    this.destY = destY;
    this.destW = destW;
    this.destH = destH;
    this.timeout = undefined;

}

Character.prototype = {
    draw: function() {
        return ctx.drawImage(this.model, this.srcX, this.srcY, this.srcW, this.srcH,
                    this.destX, this.destY, this.destW, this.destH);
    },

    animate: function(claymation) {
        var top = this; <<<<<--------Set the this variable
        var queue = (function() {
            var that = this;
            var active = false;
            if (!this.active) {
                (function runQueue(i) {
                    that.active = true;
                    var length = claymation.length -1;      
    >>>>-Set the timeout    top.timeout = setTimeout(function() {
                        claymation[i].action();
                        if ( i < length ) {
                            runQueue(i + 1);
                            if (i === length - 1) {
                                that.active = false;
                            }
                        }
                    }, claymation[i].time);
                })(0);
            }
        })();
        return queue;
    },

    update: function(callback) {
        callback();
    },
    unbind: function() {
        console.log(this.timeout); < Logs undefined
        clearTimeout(this.timeout);
        console.log(this.timeout); < Also logs undefined?
    }
}

更新:

我打電話取消綁定:

player = new Character(playerModel, 0, 130, 100, 100, 150, 150, 100, 100)
        if (e.which === 39) {
            player.unbind();
            key = undefined;
        }

完整的源代碼: https : //github.com/Gacnt/FirstGame/blob/master/public/javascripts/superGame.js#L50-L77

您的animate功能混亂了。 你已經看到了需要存儲在this引用的一個額外的變量( thattop ,等等),因為它從調用更改調用和函數的功能,但你卻沒有做是正確的。

var top = this;
var queue = (function() {
    var that = this;
    var active = false;
    if (!this.active) {
        // use
        that.active = true;
        // or
        top.timeout = …;
        // or
        that.active = false;
    }
})();

雖然top是正確的,將引用Character上,您調用該方法的實例, that絕對不是-它會引用全局上下文( window ),這是默認this在正常(立即)值調用函數(表達)秒。 因此, this.active幾乎也沒有值,並且您的timeout屬性也未設置。 另請注意,IIFE不return任何內容,因此queue將是undefined

相反,您似乎想使用該局部active變量。 然后就做吧! 您不必使用某些Java- this類似關鍵字來引用“本地”一個-變量只是作用域鏈中的下一個,因此將使用它。

我不確定,但看起來像您想要的

Character.prototype.animate = function(claymation) {
    var that = this; // variable pointing to context
    var active = false; // again, simple local variable declaration
    if (!active) {
       (function runQueue(i) {
            active = true; // use the variable
            var length = claymation.length -1;      
            that.timeout = setTimeout(function() { // use property of "outer" context
                claymation[i].action();
                if ( i < length ) {
                    runQueue(i + 1);
                    if (i + 1 === length) {
                        active = false; // variable, again!
                    }
                }
            }, claymation[i].time);
        })(0);
    }
};

貝爾吉在說的是:

animate: function(claymation) {
    var top = this;

在這里,您設置了一個引用實例的頂部(我寧願稱其為character,所以您知道它是Character的實例)。 然后,你有一個有它自己的執行上下文和這個新值的IIFE:

    var queue = (function() {
        var that = this;

這里設置的該在IIFE,未設置成默認為全局/窗口對象,或者如果在嚴格模式下,將保持不確定。

        var active = false;
        if (!this.active) {

因此,在這里您將獲得window.active ,這可能是第一次未定義,因此測試是正確的。 稍后您執行:

            (function runQueue(i) {
                that.active = true;

window.active設置為true。 另外,您正在執行:

            (function runQueue(i) {
               ...
            })(0);

如果只是傳遞一個固定值,則不需要IIFE,只要在有i地方都使用0並刪除IIFE,就可以使用函數體,而在作用域鏈上不需要該多余的對象。

最后,兩個IIFE都不返回任何內容,因此隊列保持未定義狀態,因此:

    })();
    return queue;

返回udefined值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM