JavaScript OOP:我是否错过了变量作用域和匿名函数



我得到一些奇怪的行为,因为我试图实现一点事件处理到我的javascript游戏。我不是JavaScript专家,我觉得我错过了一些重要的东西,但我不知道哪里出了问题。

我设置了EventManager "class":

function EventManager(events) {
    var _events;
    this.addEventCallback = function(eventName, callback) {
        _events[eventName].push(callback);
    }
    this.fireEvent = function(eventName) {
        for (var i = 0; i < _events[eventName].length; i++) {
            _events[eventName][i]();
        }
    }
    // constructor
    __construct = function(that) {
        _events = [];
        for (key in events) {
            _events[events[key]] = new Array();
        }
    }(this)
}
在我的GameObject类中,我像这样使用我的EventManager:
function GameObject() {
    // define event ids
    var _events = {
        MOVE_START: 0,
        MOVE_STOP: 1
    }
    var _eventManager;
    // how i fire the event:
    this.moveLeft = function() {
        if (!_isMoving()) {
                _eventManager.fireEvent(_events.MOVE_START);
                _velocity = new Vector(-1, 0);
        }
    }
    // event registration "interface"
    this.onMoveStart = function(fn) {
        _eventManager.addEventCallback(_events.MOVE_START, fn);
    }
    this.onMoveStop = function(fn) {
        _eventManager.addEventCallback(_events.MOVE_STOP, fn);
    }
    // constructor
    __construct = function(that) {
        _eventManager = new EventManager(_events);
    }(this);
}

然后我测试一下:

    for (var i = 0; i < _gameObjects.length; i++) {
        console.log("event handler to object number " + i);
        _gameObjects[i].onMoveStart(function() {
            console.log("object number " + i + " started moving");
        });
    }

我希望当我移动第一个对象时输出是"对象编号0开始移动",当我移动第二个对象时输出是"对象编号1开始移动",以此类推。

输出总是:"object number 3 started moving"。它总是说物体3,不管我移动哪个物体。对我来说最奇怪的部分是,我的_gameObjects -Array中只有3个对象,所以我至少希望它说"对象2开始移动"。

I tried doing this:

    for (var i = 0; i < _gameObjects.length; i++) {
        var num = i;
        console.log("event handler to object number " + num);
        _gameObjects[i].onMoveStart(function() {
            console.log("object number " + num + " started moving");
        });
    }

那么,她的输出总是:"对象2开始移动"

我确信这些对象并不都是相同的,因为我可以移动我想要的对象。

非常感谢你的帮助!

你的问题的答案是"是",即你确实错过了JS匿名函数中变量作用域的一些东西。我推荐你阅读Javascript闭包入门教程,这篇文章的全文引用在这里:How do Javascript闭包工作?

要使测试代码工作,您可以这样做:
function notifyStart(i) {
    return function() {
        console.log("object number " + i + " started moving");
    }
}
for (var i = 0; i < _gameObjects.length; i++) {
    _gameObjects[i].onMoveStart( notifyStart(i) );
}

相关内容

  • 没有找到相关文章

最新更新