原型内的功能不起作用

时间:2014-02-18 17:47:26

标签: javascript

使用以下代码触发keydown事件时,不会调用onKeyDown函数:

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语法无法完成工作的任何想法?提前谢谢。

3 个答案:

答案 0 :(得分:7)

您的操作顺序是window.addEventListener来电失败的原因。

您永远不会在第一个版本中传递onKeyDown 函数,而是传递onKeyDown 变量的值,在致电时undefined

“传统”版本起作用的原因是由于所谓的“悬挂”。

varfunction声明被提升到写入函数的顶部。

即使您可能将代码编写为:

缩短以用于演示目的
Game.prototype.setEventHandlers = function() {
    // Keyboard events
    window.addEventListener("keydown", onKeyDown, false);

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

它实际上执行为:

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

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

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

如果您要使用函数声明

<子>即
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代码通常更安全。这有助于防止这种操作顺序错误。

答案 1 :(得分: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);

}

答案 2 :(得分:0)

函数声明(function name() {}样式)将其变量和值提升到作用域的顶部,但是分配给变量(var fn = function() {}样式)的匿名函数不是。在您的代码中,变量声明被提升但将函数赋值给该变量。

所以你的代码实际上是这样解析的:

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

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

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

当您将onKeyDown传递给addEventListener时,{{1}}未定义。