Лучший способ написания (javascript)

#javascript #oop #class #function #object

#javascript #ооп #класс #функция #объект

Вопрос:

Вероятно, здесь недостаток понимания javascript:

 engine.keyboard = {};   // keyboard object

engine.keyboard.key = {
_pressed: {},

UP: 38,
DOWN: 40,
LEFT: 37,
RIGHT: 39,

isDown: function(keyCode)
{
    return this._pressed[keyCode];
},

onKeyDown: function(event)
{
    this._pressed[event.keyCode] = true;
},

onKeyUp: function(event)
{
    delete this._pressed[event.keyCode];
}

}

engine.keyboard.addListeners = function()
{
window.addEventListener('keydown', engine.keyboard.key.onKeyDown, false);
window.addEventListener('keyup', engine.keyboard.key.onKeyUp, false);
}
  

Когда я вызываю, engine.keyboard.key.isDown(38) я получаю ошибку, которая this._pressed не определена.

Возможно, есть лучший способ определить все это? Я работаю над очень простой игрой, но просто экспериментирую с различными способами разделения всего этого. Итак, на данный момент у меня есть engine , engine.keyboard engine.camera и engine.map которые все делают там собственные крошечные биты. Я использовал то же самое engine.EXAMPLE = {} в начале каждого из них. Возможно, это неэффективно?

Приветствия.

Комментарии:

1. Немного не по теме, но не вернет ли ваш isDown() метод либо true , либо undefined ? Это будет (вероятно, в зависимости от того, как вы его используете) по-прежнему работать, но, на мой взгляд, было бы лучше вернуть true or false , что вы могли бы сделать с return this._pressed[keyCode] || false; .

2. Улучшает ли это производительность из интереса или просто лучше с точки зрения кодирования? Хотя комментарий хороший.

Ответ №1:

Проблема в том, что вы передаете функцию только как обработчик событий. При этом он больше не имеет отношения к engine.keyboard.key объекту.

То, на что this ссылается функция внутри, зависит от того, как она вызывается. Для того, чтобы this ссылаться на engine.keyboard.key , функция должна вызываться как

 engine.keyboard.key.onKeyDown()
  

Итак, что вам нужно, это:

 window.addEventListener('keydown', function(event) {
    engine.keyboard.key.onKeyDown(event);
}, false);

window.addEventListener('keyup', function(event) {
    engine.keyboard.key.onKeyUp(event);
}, false);
  

Также обратите внимание, что addEventListener это недоступно в IE8. Там вам придется использовать attachEvent .

Я предлагаю прочитать отличные статьи об обработке событий на qurirksmode.org .


Дальнейшее предложение:

Чтобы каким-то образом отделить функцию от объекта, вы можете создать замыкание:

 engine.keyboard = {};  
engine.keyboard.key = (function() {
    var _pressed = {};

    var key = {
        UP: 38,
        DOWN: 40,
        LEFT: 37,
        RIGHT: 39,

        isDown: function(keyCode)  {
            return _pressed[keyCode];
        },

        onKeyDown: function(event) {
            _pressed[event.keyCode] = true;
        },

        onKeyUp: function(event) {
            delete _pressed[event.keyCode];
        }
    }
    return key;
}());
  

Здесь нет проблем с передачей, engine.keyboard.key.onKeyDown поскольку функции больше не зависят от this . _pressed теперь это переменная в области видимости, в которой определены функции, поэтому у них есть к ней полный доступ.

Это просто для того, чтобы показать, что можно сделать.

Комментарии:

1. Могу ли я просто уточнить, как работает функция —-= (—- extra(? И что делают скобки final ()?

2. @ChrisEvans: Это самозапускающаяся или немедленная функция. Вы определяете функцию и выполняете ее немедленно. Например. эти два являются одинаковыми: function bar(){alert(1);}; bar(); и (function bar(){alert(1);}()) . Как вы, вероятно, знаете, добавляя () к функции, вы вызываете ее, и вместо того, чтобы сначала присваивать функцию переменной, вы вызываете ее немедленно.

3. Вау, фантастический ответ. Я читал о непосредственных функциях, но в том, как это отображалось на экране, я не мог уловить никакого смысла. Я проголосую за ваши ответы, когда мне, в конце концов, разрешат!

4. @ChrisEvans: Ну, вы можете принять это 😉 (щелкнув по контуру галочки рядом с ним). Таким образом, вы также помечаете вопрос как решенный.

Ответ №2:

Это стандартный обработчик ключей. Я не верю, что есть лучший способ что-то делать.

Комментарии:

1. На самом деле это не отвечает на вопрос OP. Почему он выдает ошибку?