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

JavaScript加载游戏数据时如何保留数组内的对象引用?

问题本质

你遇到的引用断开问题,根源是JSON.parse()会生成全新的对象树,读档时直接执行gameData = loadData会让gameData指向新的对象树,而全局声明的farm、hut还是指向初始化时创建的旧对象,两者完全脱离关联,自然不会同步更新。
初始化时farm === gameData.buildingArray[0]为真,读档后该判断为假,就是引用断开的直接证明。

方案1:最小改动修复(无需调整现有业务代码)

不需要修改其他逻辑,仅调整loadGame的实现:

  1. 不要直接替换整个gameData对象,而是把存档数据覆写到原有gameData对象上,保留原对象的引用地址
  2. 手动把全局的farm、hut重新指向gameData.buildingArray里的对应元素,恢复引用关联

修改后的loadGame代码:

function loadGame() {
    const savedData = localStorage.getItem(localStorageName)
    if (!savedData) return
    const loadData = JSON.parse(savedData)
    // 把存档数据覆写到原gameData对象,不替换引用
    Object.assign(gameData, loadData)
    // 恢复全局变量和数组元素的引用关联
    farm = gameData.buildingArray[0]
    hut = gameData.buildingArray[1]
    console.log("Data Loaded")
}

方案2:架构重构(更易维护,从根源避免引用问题)

你单独声明全局建筑变量是为了调用方便,但散放的全局变量很容易出现引用不同步的问题,建议把所有游戏状态收敛到gameData单一根节点下:

// 所有建筑数据统一放在gameData下,不单独声明全局变量
const gameData = {
  // 用对象存储建筑,方便按名称直接访问
  buildings: {
    farm: { amount: 0 },
    hut: { amount: 0 }
  },
  // 如果需要数组格式做遍历,用getter动态生成,永远和对象数据同步
  get buildingArray() {
    return Object.values(this.buildings)
  }
}

// 存读档逻辑
function saveGame() {
    localStorage.setItem(localStorageName, JSON.stringify(gameData))
    console.log("Data Saved")
}

function loadGame() {
    const savedData = localStorage.getItem(localStorageName)
    if (savedData) {
        const loadData = JSON.parse(savedData)
        Object.assign(gameData, loadData)
        console.log("Data Loaded")
    }
}

后续访问建筑属性直接用gameData.buildings.farm.amount即可,可读性和维护性都更高,新增建筑时只需要在gameData.buildings里添加对应项,不需要手动维护buildingArray,也不会再出现引用不同步的问题。

注意事项

如果后续建筑类型增多,不要用数组下标对应建筑类型,建议给每个建筑添加唯一的type字段做标识,避免数组顺序调整后出现数据错位的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 16:36:02