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

如何优化我的JavaScript井字棋代码使其更整洁?

井字棋代码优化建议

你的井字棋功能正常,但代码存在不少重复逻辑和冗余操作,以下是具体的优化方向和改进后的代码:

核心优化点

1. 批量处理重复的DOM元素选择

原代码中逐个获取sn0到sn8的DOM节点,可通过属性选择器批量获取,避免重复代码:

// 替换逐个选择的sn0-sn8
const snCells = document.querySelectorAll('[id^="sn"]');

2. 简化玩家状态存储

不需要创建<p>元素存储玩家名称,直接用字符串变量即可,减少DOM操作开销:

// 替换原有的currentPlayer DOM元素定义
const PLAYER_TOMATO = "tomato";
const PLAYER_FLOWER = "flower";
let currentPlayer = PLAYER_TOMATO;

3. 消除重复的类操作逻辑

checkWinner和restartGame中大量重复的类添加/移除代码,可通过循环批量处理:

  • 在checkWinner中:
// 替换原有的9个if判断
snCells.forEach((cell, index) => {
  cell.classList.remove(PLAYER_TOMATO, PLAYER_FLOWER);
  if (options[index] === PLAYER_TOMATO) {
    cell.classList.add(PLAYER_TOMATO);
  } else if (options[index] === PLAYER_FLOWER) {
    cell.classList.add(PLAYER_FLOWER);
  }
});
  • 在restartGame中:
// 替换原有的9次类移除操作
snCells.forEach(cell => {
  cell.classList.remove(PLAYER_TOMATO, PLAYER_FLOWER);
});

4. 使用符合规范的自定义属性

将HTML中的cellIndex改为data-cell-index(符合HTML5自定义属性规范),获取方式改为:

const cellIndex = this.dataset.cellIndex;

5. 优化变量与常量的可读性

将魔法字符串(如"tomato"、"flower")定义为常量,后续修改更方便,代码可读性更高。


优化后的完整代码

const cells = document.querySelectorAll(".cell");
const statusText = document.querySelector("#statusText");
const restartBtn = document.querySelector("#restartBtn");
const snCells = document.querySelectorAll('[id^="sn"]');

// 定义玩家常量,避免魔法字符串
const PLAYER_TOMATO = "tomato";
const PLAYER_FLOWER = "flower";
const winConditions = [
    [0, 1, 2],
    [3, 4, 5],
    [6, 7, 8],
    [0, 3, 6],
    [1, 4, 7],
    [2, 5, 8],
    [0, 4, 8],
    [2, 4, 6]
];

let options = Array(9).fill("");
let currentPlayer = PLAYER_TOMATO;
let running = false;

initializeGame();

function initializeGame() {
    cells.forEach(cell => cell.addEventListener("click", cellClicked));
    restartBtn.addEventListener("click", restartGame);
    updateStatusText();
    running = true;
}

function cellClicked() {
    const cellIndex = this.dataset.cellIndex;

    if (options[cellIndex] !== "" || !running) {
        return;
    }

    updateCell(this, cellIndex);
    checkWinner();
}

function updateCell(cell, index) {
    options[index] = currentPlayer;
    cell.textContent = currentPlayer;
}

function changePlayer() {
    currentPlayer = currentPlayer === PLAYER_TOMATO ? PLAYER_FLOWER : PLAYER_TOMATO;
    updateStatusText();
}

function updateStatusText() {
    statusText.textContent = `${currentPlayer}'s turn`;
}

function checkWinner() {
    let roundWon = false;

    for (const condition of winConditions) {
        const [a, b, c] = condition;
        const cellA = options[a];
        const cellB = options[b];
        const cellC = options[c];

        if (cellA === "" || cellB === "" || cellC === "") continue;
        if (cellA === cellB && cellB === cellC) {
            roundWon = true;
            break;
        }
    }

    if (roundWon) {
        statusText.textContent = `${currentPlayer} wins!`;
        running = false;
    } else if (!options.includes("")) {
        statusText.textContent = `Draw!`;
        running = false;
    } else {
        changePlayer();
    }

    // 批量更新snCells的类
    snCells.forEach((cell, index) => {
        cell.classList.remove(PLAYER_TOMATO, PLAYER_FLOWER);
        if (options[index] === PLAYER_TOMATO) {
            cell.classList.add(PLAYER_TOMATO);
        } else if (options[index] === PLAYER_FLOWER) {
            cell.classList.add(PLAYER_FLOWER);
        }
    });
}

function restartGame() {
    currentPlayer = PLAYER_TOMATO;
    options = Array(9).fill("");
    updateStatusText();
    cells.forEach(cell => cell.textContent = "");
    running = true;

    // 批量移除snCells的类
    snCells.forEach(cell => {
        cell.classList.remove(PLAYER_TOMATO, PLAYER_FLOWER);
    });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 17:35:16