簡體   English   中英

調用事件后,javascript構造函數屬性變為undefined

[英]javascript constructor property becomes undefined after event is called

var Context = {
    canvas: null,
    context: null,
    create: function(canvas_tag_id, size){
        this.canvas = document.getElementById(canvas_tag_id);
        this.canvas.width = size[0];
        this.canvas.height = size[1];
        this.context = this.canvas.getContext('2d');
        return this.context;
    },
    fps:1/30
};

$(function(){

// Initialize
Context.create('canvas', [798, 652]);

var s_size = [Context.canvas.width, Context.canvas.height]; // screen size

function Player(){
    this.rect = [0, s_size[1]-40, 20, 40];
    this.color = 'blue';

    this.create = function(){
        // function for creating player object

        Context.context.beginPath();
        Context.context.fillStyle = this.color;
        Context.context.rect(
            this.rect[0], this.rect[1], this.rect[2], this.rect[3]);
        Context.context.fill();
    };

    this.control = function(){
        // player movement control function

        if (event.which == 39 || event.keyCode == 39){
            alert(this.rect);
        }
    };

    this.update = function(){
        this.rect[0] += 1;
    }
}

// player instance creation

var archie = new Player();

// game loop functions

function events(){
    // Keydown events

    function keydown(){
        window.addEventListener('keydown', archie.control);
    }

    keydown();
}

function update(){
    archie.update();
}

function render(){
    Context.context.clearRect(0, 0, canvas.width, canvas.height);

    archie.create();
}

function game(){
    events();
    update();
    render();
}

setInterval(game, Context.fps);
});

正如您所看到的,問題不在於代碼的組織而在於事件處理程序,因為即使在事件處理程序之后創建了播放器類的更新方法,它也能正常工作。 究竟是什么問題在這里,我該如何解決?

在事件處理程序內部, this始終是事件處理程序綁定的元素,而不是傳入函數的構造函數。

要編寫更短的代碼,你正在做

var Player = function() {

    this.rect = "something";

    this.control = function(){
        if (event.which == 39 || event.keyCode == 39){
            alert(this.rect); // NOPE ... this is the element
        }
    };
}

var archie = new Player(); // create instance

window.addEventListener('keydown', archie.control); // some function in the instance

如果您只需將對象作為this值,請使用bind

window.addEventListener('keydown', archie.control.bind(archie));

另請注意,事件處理程序回調缺少event參數,並且依賴於全局event ,這在所有瀏覽器(Firefox)中都不受支持,因此您應該這樣做

this.control = function(event) {...

我經常使用的另一個解決方案是this值存儲在另一個變量ex中。 self並在每個地方使用該副本,因此它可能是:

var Player = function() {

    var self = this;

    self.rect = "something";

    self.control = function(event){
        if (event.which == 39 || event.keyCode == 39){
            alert(self.rect);
        }
    };
}

這可以保證您使用所需的內容,因為this是基於方法執行的上下文。

暫無
暫無

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

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