2014-02-18 6 views
1

OnKeyDown функция не вызывается, когда KeyDown событие вызывается, используя следующий код:Функция внутри прототип не работает

Game.prototype.setEventHandlers = function() { 
    // Keyboard events 
    window.addEventListener("keydown", onKeyDown, false); 
    window.addEventListener("downup", onKeyUp, false); 

    // Mouse events 
    window.addEventListener("mousemove", onMouseMove, false); 
    window.addEventListener("click", onMouseClick, false); 

    // Window events 
    window.addEventListener("resize", onWindowResize, false); 

    var onKeyDown = function(e) { 
     alert("HI!"); 
    }; 
} 

Если я заменю его с традиционной функцией синтаксиса это работает просто отлично:

function onKeyDown() { 
    alert("HI!"); 
} 

Любые идеи относительно того, почему синтаксис var onKeyDown = function не выполняет эту работу? Заранее спасибо.

+1

@Skwal: Не имеет значения, где это * объявлено *, там, где это * инициализировано *, это проблема. –

ответ

7

Ваш заказ операций является причиной сбоя вызовов window.addEventListener.

Вы никогда не передавая функциюonKeyDownв первой версии, вы передаете значение onKeyDownпеременной, который в момент вызова является undefined.

Причина, по которой «традиционная» версия работает, связана с так называемым «подъемным устройством».

var и function декларации поднимаются к верхней части функции, что они написаны в

Даже если вы могли бы написать код, как:.

Укороченный для демонстрационных целей
Game.prototype.setEventHandlers = function() { 
    // Keyboard events 
    window.addEventListener("keydown", onKeyDown, false); 

    var onKeyDown = function(e) { 
     alert("HI!"); 
    }; 
} 

It фактически исполняется как:

Game.prototype.setEventHandlers = function() { 
    var onKeyDown; 

    // Keyboard events 
    window.addEventListener("keydown", onKeyDown, false); 

    onKeyDown = function(e) { 
     alert("HI!"); 
    }; 
} 

Если вы должны были использовать объявление функции вместо этого

I.E.
Game.prototype.setEventHandlers = function() { 
    // Keyboard events 
    window.addEventListener("keydown", onKeyDown, false); 

    function onKeyDown(e) { 
     alert("HI!"); 
    } 
} 

код фактически выполняет как:

Game.prototype.setEventHandlers = function() { 
    function onKeyDown(e) { 
     alert("HI!"); 
    } 

    // Keyboard events 
    window.addEventListener("keydown", onKeyDown, false); 
} 

код очистки инструментов, таких как jslint пометит такого рода несоответствий. Обычно безопаснее писать JS-код так, как он будет выполняться. Это помогает предотвратить ошибку такого порядка операций.

+0

Спасибо за ваш ответ. Какая функция объявления вы бы сказали лучше для этого сценария? – jskidd3

+0

@ jskidd3, это не имеет значения. Я рекомендую записать код в следующем порядке: объявление переменной, объявление функции, инициализация переменных, выполнение. В вашем случае вы положили инициализацию переменных после выполнения основного тела функции. Какая декларация функции, которую вы решите использовать, зависит от вас. – zzzzBov

+2

@ jskidd3: Одна объективная причина использовать функцию * Объявление * (ваш пример функции onKeyDown), а не выражение функции (ваш пример 'var onKeyDown = function) состоит в том, что объявление дает функции собственное имя, которое может быть полезными в столах вызовов и т. д. (Есть что-то, называемое выражением именованной функции, но оно не будет полезно в вашей ситуации и не работает корректно на IE8 ...). В следующей версии спецификации JavaScript форма выражения в вашем примере также дать функции реальное имя, но не с текущими двигателями. –

2

Любые идеи относительно того, почему синтаксис var onKeyDown = не выполняет эту работу?

На данный момент вы передаете onKeyDown к addEventListener, это не имеет значения еще. Назначение значения имеет место в конце функции после того, как вы уже вызвали addEventListener.

Переместить задание сверху:

Game.prototype.setEventHandlers = function() { 

    var onKeyDown = function(e) { 
     alert("HI!"); 
    }; 

    // Keyboard events 
    window.addEventListener("keydown", onKeyDown, false); 
    window.addEventListener("downup", onKeyUp, false); 

    // Mouse events 
    window.addEventListener("mousemove", onMouseMove, false); 
    window.addEventListener("click", onMouseClick, false); 

    // Window events 
    window.addEventListener("resize", onWindowResize, false); 

} 
+0

Ошибка ах школьника! Вы бы сказали, что лучше назначить функцию переменной в этом сценарии или более разумно использовать синтаксис функции(), который определяет ее во время выполнения? – jskidd3

+0

@ jskidd3: Это действительно зависит от вас. –

0

функции декларации (function name() {} стиль) имеют свои переменные и значение водрузили на вершине сферы, но анонимные функции присваивается переменной (var fn = function() {} стиле) не являются ,В вашем коде объявление переменной отображается, но не назначение функции этой переменной.

Так что ваш код фактически анализируется так:

Game.prototype.setEventHandlers = function() { 
    var onKeyDown; 

    window.addEventListener("keydown", onKeyDown, false); 

    onKeyDown = function(e) { ... }; 
}; 

Так onKeyDown не определен, когда вы передаете его addEventListener.

Смежные вопросы