![](/img/trans.png)
[英]class property becomes undefined after adding an eventlistener inside the constructor
[英]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.