简体   繁体   中英

Function inside prototype not working

The onKeyDown function is not called when the keydown event is fired using the following code:

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!");
    };
}

If I replace it with the traditional function syntax it works just fine:

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

Any ideas as to why the var onKeyDown = function syntax doesn't get the job done? Thanks in advance.

Your order of operations is the reason that the window.addEventListener calls are failing.

You're never passing the onKeyDown function in the first version, you're passing the value of the onKeyDown variable , which at the time of calling is undefined .

The reason the "traditional" version works, is due to what's called "hoisting".

var and function declarations are hoisted to the top of the function that they are written in.

Even though you might write code as:

Shortened for demonstration purposes
 Game.prototype.setEventHandlers = function() { // Keyboard events window.addEventListener("keydown", onKeyDown, false); var onKeyDown = function(e) { alert("HI!"); }; } 

It actually executes as:

 Game.prototype.setEventHandlers = function() { var onKeyDown; // Keyboard events window.addEventListener("keydown", onKeyDown, false); onKeyDown = function(e) { alert("HI!"); }; } 

If you were to use a function declaration instead

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

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

The code actually executes as:

 Game.prototype.setEventHandlers = function() { function onKeyDown(e) { alert("HI!"); } // Keyboard events window.addEventListener("keydown", onKeyDown, false); } 

Code cleanup tools such as jslint will flag these sorts of inconsistencies. It's generally safer to write JS code in the way that it's going to execute. This helps prevent this sort of order of operations mistake.

Any ideas as to why the var onKeyDown = function syntax doesn't get the job done?

At the moment you pass onKeyDown to addEventListener , it doesn't have a value yet. The assignment of the value takes place at the end of the function, after you already called addEventListener .

Move the assignment to the top:

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);

}

Function declarations ( function name() {} style) have their variable and value hoisted to the top of the scope, but anonymous functions assigned to a variable ( var fn = function() {} style) are not. In your code, the variable declaration is hoisted but not the assignment of the function to that variable.

So your code is actually being parsed like this:

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

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

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

So onKeyDown is undefined when you pass it to addEventListener .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM