Javascript原型不是函数

javascript prototype...is not afunction

本文关键字:函数 原型 Javascript      更新时间:2023-09-26

我总是得到错误,player.draw()不是一个函数,但我找不到问题。Player类存在,但没有draw方法:(希望我能给你更多的细节,但没有更多。谢谢你的帮助,下面是代码:

var version = "0.0.1";
var is_playing = false;
init();
function init(){
    background_canvas = document.getElementById("background-canvas");
    background_ctx = background_canvas.getContext("2d");
    main_canvas = document.getElementById("main-canvas");
    main_ctx = main_canvas.getContext("2d");
    requestaframe = (function(){
        return  window.requestAnimationFrame            ||
                window.webkitRequestAnimationFrame      ||
                window.mozRequestAnimationFrame         ||
                window.oRequestAnimationFrame           ||
                window.msRequestAnimationFrame          ||
                function(callback){ window.setTimeout(callback, 1000/60); };
    })();
    player = new Player();
    start_loop();
}
function mouse(e){
    var x = e.pageX - document.getElementById("game-holder").offsetLeft;
    var y = e.pageY - document.getElementById("game-holder").offsetTop;
    document.getElementById("x").innerHTML = x;
    document.getElementById("y").innerHTML = y;
}
function Player(){
    this.color = "yellow";
}
Player.prototype.draw = function(){
    main_ctx.fillStyle = this.color;
    main_ctx.arc(205, 70, 25, 0, 2*Math.PI);
    main_ctx.fill();    
};
function clearStage(){
    main_ctx.clearRect(0, 0, 800, 600);
}
function start_loop(){ is_playing = true; loop(); }
function stop_loop(){ is_playing = false; }
function loop(){
    clearStage();
    main_ctx.fillStyle = "blue";
    main_ctx.fillRect(175, 100, 450, 450);
    player.draw();
    if(is_playing) requestaframe(loop);
}

您尝试使用提升,但似乎没有完全理解它。

一般来说,提升将函数和变量声明(不是赋值!)移动到当前作用域的顶部。这就是为什么你可以在实际声明init()方法之前调用它的原因。

把你的代码剥离一下,它看起来像这样

init();
function init() { ... }
function Player() { ... }
Player.prototype.draw = ...;

在提升之后(所以你的代码被评估的方式)它看起来像这样:

function init() { ... }
function Player() { ... }
init();
Player.prototype.draw = ...;

因此,您可以清楚地看到,当您第一次调用init()时,draw()方法尚未附加到Player原型,因此它是未定义的。

简单的解决方案是改变代码的顺序,并将init()调用移到底部。

函数声明在代码执行开始之前被处理,所以你可以在init声明之前调用init:

init();
function init(){...}

赋值发生在代码执行的后面,所以赋值:

Player.prototype.draw = function(){...}
当你调用initPlayer.prototype时,

没有发生。当你调用init时,Draw

未定义。

将调用移动到脚本的底部,或者至少在所有赋值Player.prototype.