#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
orfalse
, что вы могли бы сделать с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. Почему он выдает ошибку?