对js范围和外部类的怀疑

时间:2013-03-04 19:59:55

标签: javascript oop box2dweb

我是js的新手。我正在使用Box2dWeb制作一个HTML5游戏,我决定我应该完全基于oop。所以我在一个名为physics.js

的单独文件中创建了这样的物理类
(function(window) 
{
function Physics(element, scale){
//init world logic
    }

Physics.prototype.debug = function(){
           //debug draw logic
};

Physics.prototype.step = function(dt){
    //step logic
};

    //making this class(or object) visible on the global scope
    //so i can create vars of this type anywhere in the application
window.Physics = Physics;
}(window));

现在我有一个主game.js文件,我在其中初始化我的所有游戏物理,图形,资源等。以下是内容:

(function(){
 function init(){
    var physics = new Physics(document.getElementById("b2dCanvas"), 30);
    console.log(physics);
    physics.debug();
}
window.addEventListener("load", init);
 }());

这个文件初始化我的Physics对象没有任何问题。最终这就是我想要的。大!但是,在此之前,文件是这样的,没有init()函数。

(function(){

    var physics = new Physics(document.getElementById("b2dCanvas"), 30);
    console.log(physics);
    physics.debug();
 }());

这显然抛出了错误Uncaught TypeError: Cannot call method 'getContext' of null。这意味着,物理构造函数被调用(此时自然element为空),而我没有调用它。怎么可能?我在game.js中的自执行功能应该初始化Physics对象吗?我错过了什么?

4 个答案:

答案 0 :(得分:2)

在完全解析HTML之前,以及在将canvas元素添加到DOM之前,您的脚本已在运行。当您添加window.addEventListener("load", init);时,您在触发window.onload事件时运行它。那时,DOM被完全解析了。

在现代浏览器中,您也可以用

替换它
document.addEventListener("DOMContentLoaded", init);

该事件将在DOM准备就绪时触发,但不会等待其他资源(如图像)(与onload不同)。

或者,只需在关闭body标签之前添加所有脚本。此时,正文中的每个HTML标记都已插入DOM中。

答案 1 :(得分:1)

  

这意味着,正在调用物理构造函数(当然也是如此)   此时元素为null)没有我调用它。怎么样   可能的?

使用以下语法 调用它:

(function(){...}());
                ^^
               call

当脚本被解析为正常页面脚本解析的一部分时,它将调用该函数,并且不会等待文档/ DOM准备好您进行操作。你想要使用某种文档'load'监听器,或者删除那个特定的语法,并在你确定DOM准备就绪时手动调用该函数。

答案 2 :(得分:0)

该错误与物理对象未准备好无关。它与其内部的代码有关,试图在调用代码时引用不在页面上的元素。

你打电话很简单

document.getElementById("b2dCanvas")

在页面上加载元素之前。当getElementById找不到任何内容时,它返回null。

那么,如果您要检查它,您的代码是什么样的

var physics = new Physics(null, 30);

,元素为空

function Physics(element, scale){  
    var ctx = element.getContext("2d");  //<-- where the error occurs since element is null

因此错误:Uncaught TypeError: Cannot call method 'getContext' of null

当你监听load事件时,这意味着元素在那里,所以它加载没有问题。处理它的其他方法是将脚本添加到页面底部。

答案 3 :(得分:0)

我的猜测是你在DOM准备好之前调用了这个函数。将脚本include包含在代码的底部,甚至更好地将所有init包装成一个窗口加载监听器。