有人可以向我解释我为什么会这样做:
未捕获的TypeError:无法读取undefined game.js:48
的属性'canvas'未捕获的TypeError:无法调用undefined game.js的方法'resize':4
看来由于某种原因,this.stage超出了start函数的范围。
//index.js
var game;
function init()
{
game = new Game(document.getElementById('canvas'));
}
function resize()
{
game.resize();
}
_
//game.js
function Game(canvas)
{
this.canvas = canvas;
this.stage = null;
this.loader = null;
this.scaleCanvas();
this.initCreateJS();
this.loadAssets();
}
Game.prototype =
{
resize: function()
{
this.scaleCanvas(this.canvas);
this.level.resize(this.canvas.width, this.canvas.height);
this.stage.update();
},
scaleCanvas: function()
{
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;
},
initCreateJS: function()
{
this.stage = new createjs.Stage(this.canvas);
createjs.Ticker.setFPS(30);
this.stage.enableMouseOver(10);
if(createjs.Touch.isSupported())
{
createjs.Touch.enable(this.stage);
}
},
loadAssets: function()
{
manifest = [
{src:"base.png", id:"base"},
{src:"logo.png", id:"logo"}
];
this.loader = new Loader(manifest, this.start);
},
start: function()
{
this.level = new Level(4,4,this.stage.canvas.width,game.stage.canvas.height);
this.level.randomLevel();
this.level.print();
game.stage.addChild(this.level);
game.stage.update();
}
};
答案 0 :(得分:0)
考虑一下:
var Foo = function(val) {
this.val = val;
}
Foo.prototype.log = function() {
console.log('Me haz ' + this.val);
}
这里我们定义了一个非常简单的类Foo
:使用构造函数将其param分配给名为val
的属性,并使用单个方法log
处理Foo.prototype
上定义的此值。 1}}。没什么特别的:
var foo = new Foo(42);
foo.log(); // Me haz 42
现在我们定义一个简单的函数 - 将另一个函数作为参数,并调用此函数。像这样:
var fooCaller = function(cb) { cb(); }
fooCaller(function() {
console.log('I am called');
});
这很简单,对。但现在事情突然变得复杂了:
fooCaller(foo.log); // Me haz undefined
什么?显然已经调用了正确的函数(因此Me haz...
) - 但为什么this.val
是undefined
而不是42
呢?在直接调用foo.log
和通过调用者函数调用之间有什么变化?
差异是this
。请参阅,JavaScript的一个独特功能是能够切换上下文(this
引用的对象)以获取相同的函数而无需触及其正文:只有调用函数的方式很重要。有两种特殊方法可以让您明确设置this
:Function.prototype.call和Function.prototype.apply的值。例如:
var bar = new Foo(34);
bar.log(); // Me haz 34
bar.log.call(foo); // Me haz 42
如您所见,call
我已将this
对象从bar
(val
属性等于34)切换为foo
。请注意,对象“拥有”该功能并不重要。
现在让我们回到你自己的代码。这条线......
new Loader(manifest, this.start);
...显然是错误的:传递未绑定的对象方法作为回调几乎总是一个坏主意。在这种情况下,Loader最终调用存储在this.start
中的函数 - 但是当它出现时,this
将指向另一个对象。
为防止这种情况,您需要绑定上下文:传递给new Loader
另一个由this
的当前值定义的函数。最简单的方法是使用Function.prototype.bind:
new Loader(manifest, this.start.bind(this));
...这将基本上创建另一个固定值为this
的函数(由其当前值定义)。
这虽然相当广泛,但只是快速浏览了this
在JavaScript中的功能(不仅仅是关于功能,也没有双关语)))。我建议检查this answer - 以及其中提到的文章,他们肯定会很有启发性。 )