[英]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);
});
As you can see the problem isn't the organization of the code but the event handler, because the player class's update method is working just fine even though it's created after the event handler. 正如您所看到的,问题不在于代码的组织而在于事件处理程序,因为即使在事件处理程序之后创建了播放器类的更新方法,它也能正常工作。 what exactly is the problem here and how do i solve it?
究竟是什么问题在这里,我该如何解决?
Inside the event handler, this
is always the element the event handler was bound to, not the constructor for the function passed in. 在事件处理程序内部,
this
始终是事件处理程序绑定的元素,而不是传入函数的构造函数。
To write your code a lot shorter, you're doing 要编写更短的代码,你正在做
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
If you just have to have the object as the this
value, use bind 如果您只需将对象作为
this
值,请使用bind
window.addEventListener('keydown', archie.control.bind(archie));
Also note that your event handler callback is missing the event
argument, and relying on the global event
, which is not supported in all browsers (Firefox), so you should be doing 另请注意,事件处理程序回调缺少
event
参数,并且依赖于全局event
,这在所有浏览器(Firefox)中都不受支持,因此您应该这样做
this.control = function(event) {...
Another solution I often use is to store this
value in another variable ex. 我经常使用的另一个解决方案是
this
值存储在另一个变量ex中。 self
and use that copy in every place so it could be: 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 give you guarantee of use what you want, because this
is based on context of method execution. 这可以保证您使用所需的内容,因为
this
是基于方法执行的上下文。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.