2011-03-17 39 views
10

我刚开始在javascript中使用oop,我遇到了一些问题,试图从另一种方法中访问一个方法。JavaScript对象,自引用问题

这里是我的代码:

var Game = { 
initialize: function() { 
    if (canvas.isSupported()) { 
     sprites[0] = new Player(); 

     this.update(); 
    } 
}, 

update: function() { 
    for (var i = 0; i < sprites.length; i++) { 
     sprites[i].update(); 
    } 

    this.draw(); 
}, 

draw: function() { 
    this.clear(); 

    for (var i = 0; i < sprites.length; i++) { 
     sprites[i].draw(); 
    } 

    setTimeout(this.update, 10); 
}, 

clear: function() { 
    canvas.context.clearRect(0, 0, canvas.element.width, canvas.element.height); 
} 

}

但在调用Game.update()给出的是牵引方法没有定义的错误。 我找不到一个真正的解决方案。 最终我发现这个How to call a method inside a javascript object 其中的答案似乎是,我需要安全这个参考文献,如: var _this = this; 但我无法得到那个在文字符号的工作,所以我改变了代码,对象构造函数(我猜这就是它的调用方式)并添加了变量。

我再改

this.draw(); 

_this.draw(); 

和它的工作。

虽然

this.clear(); 

和this.update()仍然是相同的,他们似乎从来没有放弃在首位的错误。

任何人都可以解释为什么这是?也许可以指点我一个更好的解决方案? 在此先感谢。

更新

下面是它应该是什么:

var Game = function() { 
var _this = this; 

this.initialize = function() { 
    if (canvas.isSupported()) { 
     sprites[0] = new Player(); 

     this.update(); 
    } 
} 

this.update = function() { 
    for (var i = 0; i < sprites.length; i++) { 
     sprites[i].update(); 
    } 

    this.draw(); 
} 

this.draw = function() { 
    this.clear(); 

    for (var i = 0; i < sprites.length; i++) { 
     sprites[i].draw(); 
    } 


    setTimeout(function() { _this.update(); }, 10); 
} 

this.clear = function() { 
    canvas.context.clearRect(0, 0, canvas.element.width, canvas.element.height); 
} 

}

+0

你能展示完整的代码吗? – 2011-03-17 13:30:13

+3

+1,真是太棒了,并发布您的更新。这篇文章最后阐述了备用命名空间方法的不同之处。你今天让我成为了一个更好的编码器。 :) – Evildonald 2012-11-16 06:26:01

回答

14

当你这样做:

setTimeout(this.update, 10); 

正确的引用传递到你的“更新”功能的系统,但是当浏览器实际上是调用该功能后,它不知道什么this应该是。你可以做的,而不是为以下:

var me = this; 
setTimeout(function() { me.update(); }, 10); 

这将确保在“更新”之称,它将被this正确设置为您的对象的引用调用。

与其他一些语言不同,函数最初定义为对象的属性并不会将函数内在地绑定到该对象。以同样的方式,如果你有一个对象与propertly这是一个简单的数字:

maxLength: 25, 

好值“25”不会有什么特别做的对象;这只是一个价值。在JavaScript中,函数也是值。因此,程序员有责任确保this将被设置为适当的东西,无论何时以某种“特殊”方式调用函数。

+0

嘿,谢谢你的驱动器downvote,朋友! – Pointy 2011-03-17 13:37:19

+0

恩,对不起。我无法回想你投票。它一定是错误的点击。 – RoToRa 2011-03-18 13:45:30

+0

它可能不是你,@RoToRa - 它可能仍然是一个谜:-) – Pointy 2011-03-18 13:48:38

0

您的问题是,你使用对象文本,而不是一个实例化对象

尝试做用这种方式代替:

var Game = function() { 
    this.initialize = function() { 
    if (canvas.isSupported()) { 
     sprites[0] = new Player(); 
     this.update(); 
    } 
    }; 
    this.update = function() { 
    for (var i = 0; i < sprites.length; i++) { 
     sprites[i].update(); 
    } 

    this.draw(); 
    }; 

    this.draw = function() { 
    this.clear(); 

    for (var i = 0; i < sprites.length; i++) { 
     sprites[i].draw(); 
    } 

    setTimeout(this.update, 10); 
    }; 

    this.clear = function() { 
    canvas.context.clearRect(0, 0, canvas.element.width, canvas.element.height); 
    }; 
} 

现在用途:

var myGame = new Game(); 
+0

只是我认为的问题的一部分... – Pointy 2011-03-17 13:31:23

+2

'this'的一个非常好的参考:http://bonsaiden.github.com/JavaScript-Garden/#function.this – adrian 2011-03-17 13:33:03

+1

@Pointy:true,setTimeout是肯定会失败,但似乎你是覆盖:) – 2011-03-17 13:36:46