【问题标题】:JS Uncaught TypeError: cannot read properties of undefined (vanilla js)JS Uncaught TypeError:无法读取未定义的属性(vanilla js)
【发布时间】:2021-11-02 08:57:24
【问题描述】:

我因此失去了毛囊 =)

所以我正在为石头剪刀布页面制作 UI; 一切正常,除了随机的奇怪控制台错误。

我有一个逻辑函数、一个随机计算机选择函数和一个事件监听器。

我正在尝试这样做,因此单击图标(svg)会调用逻辑函数来处理谁赢了。

50% 的时间它都可以正常工作。我根本找不到引发错误的模式。提前致谢。

//rock paper scissor game..
//helper dictionaries for functions
const mapState = {0:"draw", 1:"win", 2:"loss"};
const mapChoices = {"rock":0, "paper":1, "scissor":2}

//function responible for computer choice
function randomizer() {
    let choices = ["rock", "paper", "scissor"];
    //chooses a random decimal from 0(inclusive) to 1(exclusive)
    randomDecimal = Math.random();
    //changes the random to 0/1/2
    randomChoice = Math.floor(randomDecimal*3);
    //finds the tool associated with the number choosen, and prints it.
    let computerChoice = choices[randomChoice];
    console.log(computerChoice);
    //return the random number (0/1/2)
    return randomChoice;
}

//game logic determining win, loss, draw.
function logic(humanInput, computerChoice) {
    
    const arrayMatrix = [[0, 2, 1],
                         [1, 0, 2],
                         [2, 1, 0]];
            let result = arrayMatrix[humanInput][computerChoice];
            console.log("logic result: " + result);
            return result;
    
    

}
//hardcoded game length
function roundsCount() {
    return 5;
}

//the DOM variables:
let tools = document.querySelectorAll(".tool");
let rock = document.querySelector("#rock");     
let paper = document.querySelector("#paper");
let scissor = document.querySelector("#scissor");
let divOutput = document.querySelector("#score");

function doRound(e){
    let humanChoice = mapChoices[e.target.id]
    let randomChoice = randomizer();
    let result = logic(humanChoice, randomChoice);
    console.log("doround result: " + result);
    return result;

}

divOutput.innerText = "Choose Your Weapon!"

tools.forEach(tool => {
    tool.addEventListener('mouseover', event => {
      tool.classList.add("selected");
    });
    tool.addEventListener('mouseout', event => {
        tool.classList.remove("selected");
      });
      tool.addEventListener('click', doRound);
  });

浏览器确定问题出在我的 logic() 函数上,特别是在 let result = arrayMatrix[humanChoice][coputerChoice] 部分

我的代码:https://codepen.io/sirbecalo/pen/KKqggEO

请随意为我的代码添加一般建议/改进,我是个新手

【问题讨论】:

  • let result = arrayMatrix[humanChoice][coputerChoice] - 脚本中没有这样的行。始终发布正确/实际的代码... “浏览器确定...” 不正确或代码不正确。两者都不应该是这样。
  • 错误告诉你arrayMatrix[humanInput] 的结果是undefined,这意味着humanInput>= arrayMatrix.length(或者可能是负数)
  • 谢谢你,你引用的代码 sn-p 是逻辑函数中第一个声明的变量。我明白你的意思,但我回顾了这一点,如你所见,前 2 个字典是 humanInput 和 ComputerChoice 如何转换为索引的,它们只能是 0/1/2,数组是 2d 3x3 矩阵,所以我不确定这将如何成为一个问题
  • 请修剪您的代码,以便更容易找到您的问题。请按照以下指南创建minimal reproducible example

标签: javascript html typeerror


【解决方案1】:

感谢您的帮助! 我认为调用错误的原因是由于事件目标(单击目标)是 SVG 内部的多边形而不是整个 svg 元素。

通过将 console.log(e.target) 添加到我的 doRound() 函数中可以观察到这一点。

现在找到一种方法对 svg 进行“分组”,这样点击内部的任何位置都会触发整个 SVG 元素。

【讨论】:

  • 请添加更多详细信息以扩展您的答案,例如工作代码或文档引用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-11-15
  • 2022-11-17
  • 2012-12-04
  • 2020-12-24
  • 2018-03-15
  • 2019-07-28
  • 2016-03-25
相关资源
最近更新 更多