尝试使用 localStorage 在 JavaScript 中保存和加载带有对象的数组时出错

Posted

技术标签:

【中文标题】尝试使用 localStorage 在 JavaScript 中保存和加载带有对象的数组时出错【英文标题】:Errors when trying to use localStorage to save and load arrays with objects in JavaScript 【发布时间】:2017-09-06 01:54:57 【问题描述】:

我目前正在开发一款游戏,作为我在初学者编程课程中的“最终项目”。因此,核心部分是能够保存游戏数据。在游戏中,有 4 个阵列,每个阵列有 9 个位置,代表游戏中的库存。物品栏打印物品所在物品栏槽中物品的图像。一个是物品对象:

this.inventory = 1: num[1], 2: num[30], 3: num[33], 4: num[9], 5: "empty", 6: "empty", 7: "空", 8: "空", 9: "空";

每个项目(例如 num[1])都有一个 .image 属性和一个 .data 属性。 下一个数组用于定义该项目的数量:

this.inventoryStack = 1:1, 2:7, 3:99, 4:5500, 5:0, 6:0, 7:0, 8:0, 9:0;

然后是一张图片,一张是数据(数据存储在单独的数组中):

this.images = 1: num[1].image, 2: num[30].image, 3: num[33].image, 4: num[9].image, 5: 0, 6: 0、7:0、8:0、9:0;

this.data = 1: rods[0], 2: num[30].data, 3: num[33].data, 4: num[9].data, 5: 0, 6: 0, 7:0, 8:0, 9:0;

The result of these these arrays will look like this in the game:

我正在使用如下所示的localStorage方法先保存数据,然后通过单独的键盘按键恢复:

     this.save = function() 

            if(keyState[77]) 

            localStorage.setItem("inventorySave", JSON.stringify(this.inventory));
            localStorage.setItem("stackSave", JSON.stringify(this.inventoryStack));
            localStorage.setItem("imageSave", JSON.stringify(this.images));
            localStorage.setItem("dataSave", JSON.stringify(this.data));

        
    

    this.restore = function() 


            if(keyState[78] && this.restorer == true) 
            this.restorer = false;
            
            if(this.restorer == false && this.restoreTick < 2) this.restoreTick++;
            if(this.restoreTick == 1) for(var i in this.inventoryStack) this.inventoryStack[i] = 0;
            if(this.restoreTick == 2) 
                this.parser1 = JSON.parse(localStorage.getItem("inventorySave")); 
                this.parser2 = JSON.parse(localStorage.getItem("stackSave"));
                this.parser3 = JSON.parse(localStorage.getItem("imageSave"));
                this.parser4 = JSON.parse(localStorage.getItem("dataSave"));
                for(var i in this.parser1) 
                    if(this.parser1[i] != "empty") 

                    this.inventory[i] = this.parser1[i];
                    this.inventoryStack[i] = this.parser2[i];
                    this.images[i] = this.parser3[i];
                    this.data[i] = this.parser4[i];  
                    
                
                    if(!keyState[78]) 
                    this.restoreTick = 0;
                    this.restorer = true;
                    
            

    

但是,当我尝试保存然后恢复时,出现以下错误: “未捕获的 TypeError:无法在‘CanvasRenderingContext2D’上执行‘drawImage’:提供的值不是‘(CSSImageValue or htmlImageElement or HTMLVideoElement or HTMLCanvasElement or ImageBitmap or OffscreenCanvas)’类型”

我想知道,这可能是什么错误?这是我在这里的第一个问题,对于任何不好的配方或描述,我们深表歉意!我看过有关该主题的其他问题,但他们无法帮助我:(

【问题讨论】:

简单的把戏。 localStorage 和 sessionStorage,都不能保存对象或数组,只能保存字符串。在添加之前制作 JSON.stringify(object) 并在阅读时制作 JSON.parse @TypedSource ...你读过这个问题了吗? OP 正是这样做的。 哎呀,抱歉,没看到 ;) 【参考方案1】:

您不能将 HTMLImageElements 保存到 localStorage 并期望 HTMLImageElement 退出,我假设 this.images 对应。

相反,您只需要保存所需的数据,然后重新实例化图像元素。

假设this.images 是图像元素的值对象,您可以将它们复制到新对象以进行序列化以仅保存源列表,然后在恢复时重新映射到新 HTMLImageElements 列表。有几种方法可以迭代对象,但这是最古老且最兼容的方法:

this.save = function() 
  // Save a list of srcs from each Image element in this.images
  var imageSrcs = ;
  for (var key in this.images) 
    if (this.images.hasOwnProperty(key)) 
      imageSrcs[key] = this.images[key].src;
    
  
  localStorage.setItem("imageSrcsSave", JSON.stringify(imageSrcs));


this.restore = function() 
  // Restore the stored sources and instantiate NEW image elements
  // into this.images.
  var imageSrcs = JSON.parse(localStorage.getItem("imageSrcsSave"));
  this.images = ;
  for (var key in imageSrcs) 
    if (imageSrcs.hasOwnProperty(key)) 
      this.images[key] = new Image();
      this.images[key].src = imageSrcs[key];
    
  

【讨论】:

绝对正确。在您发布答案前几秒钟看到它 感谢您的快速回复!当我尝试运行保存功能时,我收到此错误:未捕获类型错误:this.images.map is not a function。现在有什么问题? @ErikLundin 哎呀。没有意识到this.images 不是一个数组(map 只在数组上,而不是对象上)。我已经更新了正确迭代对象的答案。 很好的答案,谢谢:) 是的,我意识到这也是问题所在,尽管我不知道如何解决它......再次感谢!

以上是关于尝试使用 localStorage 在 JavaScript 中保存和加载带有对象的数组时出错的主要内容,如果未能解决你的问题,请参考以下文章

尝试读取 localStorage 时出现登录错误

尝试使用 localStorage 在 JavaScript 中保存和加载带有对象的数组时出错

将localStorage值增加一

使用 LocalStorage 保存数据

使用 Vue.js 跨浏览器选项卡的反应式 localStorage 对象

XMLHttpRequest 替换元素不适用于 LocalStorage