Javascript 未捕获的类型错误:无法设置未定义的属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8877413/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 07:53:49  来源:igfitidea点击:

Uncaught TypeError: Cannot set property of undefined

javascripthtml5-canvas

提问by Ryan S.

Google Chrome is throwing "Uncaught TypeError: Cannot set property 'isDown' of undefined" but it doesn't look like anything is wrong with my code!

谷歌浏览器抛出“未捕获的类型错误:无法设置未定义的属性‘isDown’”,但看起来我的代码没有任何问题!

Important part of my variable array:

我的变量数组的重要部分:

KEY = {
    UP: 38,
    DOWN: 40,
    W: 87,
    S: 83,
    D: 68
}
pingpong = {
    fps: 60,
    pressedKeys: [],
    complete: false,
}

Key listener initialization (this is where the error is thrown):

键侦听器初始化(这是抛出错误的地方):

    for (var keyCode in KEY) {
        if (KEY.hasOwnProperty(keyCode)) {
            pingpong.pressedKeys[KEY[keyCode]] = {
                isDown: false,
                wasDown: false
            };
        }
    }
    $(document).keydown(function(e) {
        pingpong.pressedKeys[e.which].isDown = true;
    });
    $(document).keyup(function(e) {
/* This line is the issue */    pingpong.pressedKeys[e.which].isDown = false;
    });

Any Ideas?

有任何想法吗?

回答by James Allardice

The problem is that you're trying to access an element of the pressedKeysarray which does not exist. For example, if we pressed the "a" key:

问题是您正在尝试访问pressedKeys不存在的数组元素。例如,如果我们按下“a”键:

$(document).keyup(function(e) {
    //Pressed "a" so e.which == 65
    pingpong.pressedKeys[e.which].isDown = false;
});

When you initialize your array you only create elements for the properties of the KEYobject:

初始化数组时,您只为KEY对象的属性创建元素:

for (var keyCode in KEY) {
    //Iterating over KEY, which contains 5 properties...
    if (KEY.hasOwnProperty(keyCode)) {
        //Add value to pressedKeys (this happens for each of the 5 properties)
        pingpong.pressedKeys[KEY[keyCode]] = {
            isDown: false,
            wasDown: false
        };
    }
}

So pressedKeysonly contains 5 elements, corresponding to the properties of KEY. Note that a TypeError is also thrown in the keydownevent handler, as well as keyup.

所以pressedKeys只包含 5 个元素,对应于 的属性KEY。请注意,keydown事件处理程序中也会抛出 TypeError以及keyup.

To fix it, you could check that e.whichis in the KEYSobject in the event handler functions. If it's not, just ignore it. Something like this perhaps (there may be a better way, this is just what came to mind first):

要修复它,您可以检查它e.which是否在KEYS事件处理程序函数中的对象中。如果不是,请忽略它。可能是这样的(可能有更好的方法,这只是首先想到的):

$(document).keydown(function(e) {
    for(var k in KEY) {
        if(KEY[k] == e.which) {
            break; //Break out of loop and execute last line
        }
        return false; //Key not recognized, last line is not executed
    }
    pingpong.pressedKeys[e.which].isDown = true;
});

回答by user123444555621

e.whichis IE only. Real browsers use e.keyCode

e.which仅 IE。真实浏览器使用e.keyCode

jQuery Event Keypress: Which key was pressed?

jQuery 事件按键:按下了哪个键?