You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vanilla JS石头剪刀布项目随机出现Uncaught TypeError报错如何解决

问题原因与解决方案

根因分析

你遇到的随机报错有两个核心诱因:

  • 事件目标获取错误:你给.tool元素绑定了点击事件,但点击SVG图标时,e.target可能命中SVG内部的子元素(比如<path>、<g>标签),这些子元素没有设置id属性,导致mapChoices[e.target.id]返回undefined,传入logic函数后访问arrayMatrix[undefined]自然会抛出错误。报错概率随机的原因就是你有时候点到了外层带id的.tool容器,有时候点到了内部无id的SVG子元素。
  • 隐式全局变量污染:randomizer函数里的randomDecimal、randomChoice没有加let/const声明,会自动变成全局变量,多次触发点击时可能出现变量值被意外覆盖的问题。

修复方法

  1. 替换事件目标获取方式:将doRound函数里的e.target替换为e.currentTarget,e.currentTarget永远指向绑定事件的元素本身,不会随点击位置变化:
function doRound(e){
    // 替换e.target为e.currentTarget
    let humanChoice = mapChoices[e.currentTarget.id]
    let randomChoice = randomizer();
    let result = logic(humanChoice, randomChoice);
    console.log("doround result: " + result);
    return result;
}
  1. 补全变量声明:给randomizer函数里的局部变量加上let声明:
function randomizer() {
    let choices = ["rock", "paper", "scissor"];
    // 补全let声明
    let randomDecimal = Math.random();
    let randomChoice = Math.floor(randomDecimal*3);
    let computerChoice = choices[randomChoice];
    console.log(computerChoice);
    return randomChoice;
}

通用优化建议

  • 所有变量都必须加let/const声明,避免生成隐式全局变量,也可以在代码顶部加上'use strict'开启严格模式,这类错误会直接抛出提示,方便排查。
  • 可以给humanChoice增加兜底判断,避免异常值传入逻辑函数:
let humanChoice = mapChoices[e.currentTarget.id]
if (humanChoice === undefined) return
  • 目前你用JS实现的鼠标悬浮加selected类的效果,可以直接用CSS的:hover伪类实现,不需要JS绑定事件,性能更好,代码也更简洁。
  • 代码里的命名可以更规范,比如randomizer可以改成getComputerChoice,语义更清晰,后续维护更方便。

内容的提问来源于stack exchange,提问作者SirBecalo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 11:09:02