JavaScript--local storage存储的数组不可扩展的问题

数组扩展

  • 问题
  • 解析
  • 解决办法
  • 总结
  • 进一步扩展原因

问题

下列代码中的points是从本地存储中获取到的数据,我想存储到一个Map并且新增元素的时候报错


let obj = this.objectsManager._objects.get(obstacle.uuid);let points = obj.track_points;this.dyObstacleTP.set(obstacle.uuid,points);
"Cannot add property 3, object is not extensible"。

解析

在 JavaScript 中,如果你尝试向一个不可扩展的对象(例如被冻结或密封的数组)添加新属性或元素时,会遇到错误 “Cannot add property 3, object is not extensible”。
这通常是因为使用了 Object.freeze(), Object.seal() 或 Object.preventExtensions() 方法之一。
以下是这三个方法的简述:

  1. Object.freeze(obj):这个方法会冻结一个对象,这意味着你不能对这个对象添加新的属性,也不能修改或删除已有的属性。

  2. Object.seal(obj):这个方法会密封一个对象,这意味着你不能添加或删除属性,但可以修改已有的属性。

  3. Object.preventExtensions(obj):这个方法会阻止任何新的属性被添加到一个对象上,但已有的属性可以被修改或删除。

下面是一个示例代码,它会触发类似的错误:

let frozenArray = [1, 2, 3];
Object.freeze(frozenArray); // 冻结数组try {frozenArray.push(4); // 尝试添加一个新元素
} catch (e) {console.error(e.message); // 捕获并打印错误信息
}

这段代码尝试向一个被冻结的数组 frozenArray 添加一个新元素,将会抛出一个错误,因为冻结的数组是不可扩展的。

如果遇到这个问题,需要确认自己是否故意使数组不可扩展。如果不希望数组是不可扩展的,应该避免使用上述方法,或者确保在需要修改数组之前没有调用它们。

解决办法

如果数组是不小心变得不可扩展的,而我们又需要修改它,这时候可能需要创建一个新的数组来替换原先的不可扩展的数组。这样做可以通过解构赋值Array.slice(),或者其它数组复制技术来完成。比如使用解构赋值:

let newArray = [...frozenArray, 4]; // 创建一个新数组并添加新元素

请注意,如果对象是冻结的,那么你就不能改变这个状态了,因为冻结对象是不可逆的。对于密封或是非扩展的对象,没有内置的方法可以使它们重新变成正常的可扩展对象,所以需要创建新对象作为替代。

let obj = this.objectsManager._objects.get(obstacle.uuid);let points = obj.track_points;this.dyObstacleTP.set(obstacle.uuid,[...points]);

总结

Array.slice() 是一个用来复制数组的方法,可以返回数组的一个浅拷贝,原数组不会被修改。它通常用于创建一个新的数组副本,或者从现有数组中提取一个子集。

Array.slice()

let originalArray = [1, 2, 3, 4, 5];
let copiedArray = originalArray.slice(); // 复制整个数组console.log(copiedArray); // [1, 2, 3, 4, 5]

slice 方法可以接受两个参数:start 和 end,分别表示开始和结束的索引(不包含结束索引所指向的元素)。如果省略这些参数,就会复制整个数组。

解构赋值
利用 ES6 引入的解构赋值,我们也可以简洁地复制数组:

let originalArray = [1, 2, 3, 4, 5];
let copiedArray = [...originalArray]; // 使用展开运算符进行复制console.log(copiedArray); // [1, 2, 3, 4, 5]

Array.from()
Array.from() 方法可以从类数组对象或可迭代对象创建一个新的、浅拷贝的数组实例:

let originalArray = [1, 2, 3, 4, 5];
let copiedArray = Array.from(originalArray);console.log(copiedArray); // [1, 2, 3, 4, 5]

数组的 map 或 filter 方法
虽然它们不是为了复制数组而设计的,但是 map 或 filter 方法也可以返回一个新数组,因此可以通过传递一个返回每个原始元素的函数来复制数组:

let originalArray = [1, 2, 3, 4, 5];
let copiedArray = originalArray.map(e => e);console.log(copiedArray); // [1, 2, 3, 4, 5]

循环复制
传统的循环方法也能够用来复制数组:

let originalArray = [1, 2, 3, 4, 5];
let copiedArray = [];for (let i = 0; i < originalArray.length; i++) {copiedArray.push(originalArray[i]);
}console.log(copiedArray); // [1, 2, 3, 4, 5]

所有这些技术都会产生原数组的一个浅拷贝。这意味着数组里面的基础数据类型(例如 numbers, strings, booleans)将会被完全复制,但是对象类型(例如 arrays, functions, 或者其它 objects)则是通过引用复制的。如果你需要一个深拷贝,即复制数组以及数组内部嵌套的对象,那么你可能需要使用其它解决方案,如 JSON.parse(JSON.stringify(array)) 或者使用专门的深拷贝库函数。但请注意,使用 JSON.parse(JSON.stringify(array)) 会有局限性,比如它不能复制函数、正则表达式等特殊对象,并且会忽略 undefined 值。

进一步扩展原因

从 localStorage 中获取的数据默认是以字符串形式存储的。如果你尝试直接修改从 localStorage 中取回的数组数据,而没有先对其进行正确的解析,就有可能遇到问题。

例如,假设你有一个名为 points 的数组,你将其存入了 localStorage:

let points = [1, 2, 3];
localStorage.setItem('points', JSON.stringify(points));

当你从 localStorage 中检索这个数组时,需要使用 JSON.parse() 将其转换回数组格式,因为存储时数组会被转换成了字符串:

let storedPoints = localStorage.getItem('points');
if (storedPoints !== null) {points = JSON.parse(storedPoints);
}

现在 points 是一个真正的 JavaScript 数组,你可以像通常那样操作它,包括使用 push 方法来添加新元素。

但是,如果你没有进行 JSON.parse() 操作,你将得到一个表示数组内容的字符串,而不是实际的数组对象。字符串类型在 JavaScript 中是不可扩展的,也不支持 push 方法,所以尝试对其使用 push 方法会导致错误。

如果你在操作一个经过 JSON.parse() 解析后的数组还遇到 “Cannot add property x, object is not extensible” 这样的错误,那么可能你之前的某些代码已经使得这个数组变成了不可扩展的状态(通过 Object.freeze(), Object.seal() 或 Object.preventExtensions() 等)。检查你的代码,确认是否有地方对数组进行了这样的操作。

要有效地解决问题,你需要确保两件事情:

  1. 当你从 localStorage 获取数据时,确保你正确地将其从字符串解析为 JavaScript 对象或数组。
  2. 确认并排除任何可能会使数组不可扩展的代码,如 Object.freeze(), Object.seal() 或 Object.preventExtensions()。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/43446.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【大模型】大模型相关技术研究—微调

为什么要对大模型进行微调 1.成本效益&#xff1a; o 大模型的参数量非常大&#xff0c;训练成本非常高&#xff0c;每家公司都去从头训练一个自己的大模型&#xff0c;这个事情的性价比非常低。 2.Prompt Engineering 的局限性&#xff1a; o Prompt Engineering 是一种相…

视图库对接系列(GA-T 1400)十二、视图库对接系列(本级)人员数据推送

背景 人体和非机动车和机动车类似的,只是请求的参数不一样而已。人员数据推送 接入人员数据推送相对比较简单,我们只需要实现对应的接口就ok了。 具体如图: 有增删改查接口,目前的话 因为我们是做平台,我们只需要实现添加接口就可以了。 接口实现 service 层 /**** …

软件工程面向对象 超市管理系统 需求分析 系统设计 课程设计报告

1、引言 系统简述 超市管理系统的功能主要有前台管理和后台管理两个大块。其使用对象 有超市管理人员和超市销售人员两类。超市管理系统主要为了实现商品输 入、 输出管理数据的自动化&#xff0c; 提高商品统计信息的实时性&#xff0c; 减轻人工劳动强 度从而节省人力成本。实…

Perl 语言开发(九):深入探索Perl语言的文件处理

目录 1. 文件打开与关闭 1.1 打开文件 1.2 关闭文件 2. 读取文件内容 2.1 逐行读取 2.2 一次性读取整个文件 3. 写入文件内容 3.1 覆盖写入 3.2 追加写入 4. 文件测试操作 4.1 文件测试运算符 5. 文件路径操作 5.1 文件路径处理模块 5.2 获取文件路径信息 6. 文…

探索加油小程序开发:便捷出行的科技新篇章

在快节奏的现代生活中&#xff0c;出行已成为人们日常生活中不可或缺的一部分。随着移动互联网技术的飞速发展&#xff0c;各类小程序以其轻量、便捷的特点迅速融入人们的日常生活&#xff0c;其中&#xff0c;加油小程序作为智慧出行领域的一股清流&#xff0c;正悄然改变着我…

《简历宝典》04 - 简历的“个人信息”模块,要写性别吗?要放照片吗?

平时帮助小伙伴们优化简历的时候&#xff0c;我看见他们有人会写性别&#xff0c;有人不会写。 目录 1 招聘团队的考虑 2 性别是无法改变的&#xff0c;能不写就不写 3 什么情况下&#xff0c;需要写性别呢&#xff1f; 4 简历中要加照片吗&#xff1f; 1 招聘团队的考虑 …

Go语言---异常处理error、panic、recover

异常处理 Go 语言引入了一个关于错误处理的标准模式,即 error 接口,它是 Go 语言内建的接口类型,该接口的定义如下: package errorsfunc New(text string) error {return &errorString{text} }// errorString is a trivial implementation of error. type errorString st…

springboot事故车辆与违章车辆跟踪系统-计算机毕业设计源码03863

springboot事故车辆与违章车辆跟踪系统 摘 要 科技进步的飞速发展引起人们日常生活的巨大变化&#xff0c;电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流&#xff0c;人类发展的历史正进入一个新时代。…

W外链怎么样,他们家的短网址免费的吗?

W外链作为短网址服务的一种&#xff0c;体现了短网址技术的现代发展趋势&#xff0c;它不仅提供了基础的网址缩短功能&#xff0c;还扩展了一系列高级特性和增值服务&#xff0c;以适应更广泛的市场需求。根据相关参考内容&#xff0c;W外链具有以下特点和优势&#xff1a; 短域…

2024程序员行业风口和面试宝典

国际研究机构Gartner会在每年10月份左右发布下一年度的战略发展趋势预测&#xff0c;并在次年3月左右发布和网络安全相关的趋势预测。绿盟科技通过将近3年的趋势预测进行分组对比分析后发现&#xff0c;除了众人皆知的AI技术应用外&#xff0c;数据模块化、身份优先安全、行业云…

软考高级第四版备考--第13天(控制质量)Perform Quanlity Control

定义&#xff1a;为了评估绩效&#xff0c;确保项目输出完整、正确且满足客户期望而监督和记录质量管理活动执行结果的过程。 作用&#xff1a; 核实项目可交付成果和工作已经达到主要干系人的质量要求&#xff0c;可供最终验收&#xff1b;确定项目输出是否达到预期的目的&a…

01-图像基础-颜色空间

1.RGB颜色空间 RGB是一种常用的颜色空间&#xff0c;比如一幅720P的图像&#xff0c;所对应的像素点个数是1280*720&#xff0c;每一个像素点由三个分量构成&#xff0c;分别是R,G,B。 R代表红色分量&#xff0c;G代表绿色分量&#xff0c;B代表蓝色分量&#xff0c;以24位色来…

加密与安全_密钥体系的三个核心目标之不可否认性解决方案

文章目录 Pre概述不可否认性数字签名&#xff08;Digital Signature&#xff09;证书是什么证书使用流程 PKICA证书层级多级证书证书链是如何完成认证的&#xff1f; 其他疑问1. Alice能直接获取Bob的公钥&#xff0c;是否还需要证书&#xff1f;2. 为什么即使能直接获取公钥也…

理解机器学习中的潜在空间(Understanding Latent Space in Machine Learning)

1、什么是潜在空间&#xff1f; If I have to describe latent space in one sentence, it simply means a representation of compressed data. 如果我必须用一句话来描述潜在空间&#xff0c;它只是意味着压缩数据的表示。 想象一个像上面所示的手写数字&#xff08;0-9&…

vue学习day01-vue的概念、创建Vue实例、插值表达式、响应式、安装Vue开发者工具

1、vue的概念 Vue是一个用于构建用户界面的渐进式 框架 &#xff08;1&#xff09;构建用户界面&#xff1a;基于数据动态渲染页面 &#xff08;2&#xff09;渐进式&#xff1a;循序渐进的学习 &#xff08;3&#xff09;框架&#xff1a;一条完整的项目解决方案&#xff…

GenAl如何改变 DevOps 中的软件测试?

TestComplete 是一款自动化UI测试工具&#xff0c;这款工具目前在全球范围内被广泛应用于进行桌面、移动和Web应用的自动化测试。 TestComplete 集成了一种精心设计的自动化引擎&#xff0c;可以自动记录和回放用户的操作&#xff0c;方便用户进行UI&#xff08;用户界面&…

RTK_ROS_导航(2):卫星图查看

目录 1. 基于MapViz的卫星图查看 1. 基于MapViz的卫星图查看 安装 # 源码安装 mkdir -p RTK_VISION/src cd RTK_VISION/src git clone https://github.com/swri-robotics/mapviz.git --branchmelodic-eol sudo apt-get install ros-$ROS_DISTRO-mapviz ros-$ROS_DISTRO-mapviz-…

IP-GUARD如何禁止电脑自带摄像头

IP-GUARD可以通过设备管理模块禁止USB接口&#xff0c;所以USB外置摄像头很容易就可以禁止了。 但是笔记本自带摄像头无法禁止&#xff0c;配置客户端策略如下&#xff1a; device_control_unknown_mode1 device_control_unphysical_mode3

纯电车的OBD接口

尽管传统汽车的OBD接口主要用于监控和报告排放数据&#xff0c;但纯电动车辆作为零排放的交通工具&#xff0c;其设计初衷与需求截然不同。因此&#xff0c;从法律条文和车管所的规定来看&#xff0c;纯电动车辆是否仍需配置OBD接口这一问题&#xff0c;确实值得探讨。理论上&a…

ABAP中ARFC_GET_TID函数详细的使用方法

在ABAP中&#xff0c;ARFC_GET_TID 函数模块用于以十六进制形式返回终端的IP地址。这个功能在需要获取当前会话或终端的网络地址信息时非常有用&#xff0c;比如在日志记录、安全审计或网络诊断等场景中。 详细使用方法 调用函数模块 ARFC_GET_TID 函数的调用通常很直接&…