繁体   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