gpt4 book ai didi

javascript - 访问类函数?

转载 作者:行者123 更新时间:2023-11-28 08:45:12 25 4
gpt4 key购买 nike

有人可以向我解释一下为什么我会得到:

Uncaught TypeError: Cannot read property 'canvas' of undefined game.js:48

Uncaught TypeError: Cannot call method 'resize' of undefined game.js:4

由于某种原因,this.stage 似乎超出了启动函数的范围。

//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();
}
};

最佳答案

考虑一下:

var Foo = function(val) {
this.val = val;
}
Foo.prototype.log = function() {
console.log('Me haz ' + this.val);
}

这里我们定义了一个相当简单的类Foo :使用构造函数将其参数分配给名为 val 的属性,以及单个方法 log处理Foo.prototype上定义的这个值。没什么特别的:

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.valundefined ,而不是42那里?调用 foo.log 之间发生了什么变化直接或通过调用者函数?

差异是this 。你看,JavaScript 的一个独特功能是能够为同一函数切换上下文( this 引用的对象)而无需触及其主体:只有调用函数的方式才重要。有两种特殊方法允许您显式设置 this 的值: Function.prototype.callFunction.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);

... 显然是有问题的:将未绑定(bind)的对象方法作为回调传递几乎总是一个坏主意。在这种情况下,Loader最终会调用this.start中存储的函数。 - 但当它发生时,this将指向另一个对象。

为了防止这种情况,您需要绑定(bind)上下文:传递到 new Loader另一个由 this 的当前值定义的函数。最简单的方法是使用 Function.prototype.bind :

new Loader(manifest, this.start.bind(this));

...这基本上会创建另一个具有固定值 this 的函数(由其当前值定义)。

<小时/>

这虽然相当广泛,但只是快速浏览一下this JavaScript 中的函数(不仅仅是函数,没有双关语)))。我建议检查this answer - 以及其中提到的文章,它们肯定会很有启发。 )

关于javascript - 访问类函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19911765/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com