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

模块模式下如何修改变量?井字棋tileCounter点击不递增问题

模块模式中点击事件无法递增计数器的问题

你遇到的核心问题是基本类型的值传递特性导致的,具体分析如下:

问题代码

const gameBoard = (() => {
    const tiles = document.querySelectorAll('.game-board > div')
    let tileCounter = 0;
    
    tiles.forEach(tile => tile.addEventListener('click', () => {
        tileCounter++;
    }))
    
    return {tileCounter};
})();

为什么点击事件里的tileCounter++不生效?

当你写return {tileCounter}时,JavaScript会把闭包内tileCounter的当前值(初始为0)复制一份作为返回对象的tileCounter属性。因为tileCounter是Number类型(基本类型),这里是值传递,不是引用传递。

这就导致:

  • 点击事件里修改的是闭包内部的tileCounter变量
  • 你通过gameBoard.tileCounter访问的是返回对象里的那个复制值,和闭包内的变量完全独立,所以看不到变化

而直接执行gameBoard.tileCounter++时,你是直接修改返回对象的tileCounter属性,自然能看到数值变化。

解决方法

有两种常用的修复方式:

方式1:用getter返回闭包内的最新值

通过定义getter方法,让每次访问gameBoard.tileCounter时都去读取闭包内的变量:

const gameBoard = (() => {
    const tiles = document.querySelectorAll('.game-board > div')
    let tileCounter = 0;
    
    tiles.forEach(tile => tile.addEventListener('click', () => {
        tileCounter++;
    }))
    
    return {
        get tileCounter() {
            return tileCounter;
        }
    };
})();

方式2:把计数器放在返回的对象中

将tileCounter直接挂载到返回的对象上,点击事件修改这个对象的属性(对象是引用类型,修改的是同一个内存地址的值):

const gameBoard = (() => {
    const tiles = document.querySelectorAll('.game-board > div')
    const boardState = {
        tileCounter: 0
    };
    
    tiles.forEach(tile => tile.addEventListener('click', () => {
        boardState.tileCounter++;
    }))
    
    return boardState;
})();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 21:30:53