如何解决为什么将子数组/对象的属性设置为其索引最高的同级的值?
我有一个类定义的对象,其中包含另一个类定义的对象的数组。 子类定义的对象具有一个对象数组,这些对象数组来自全局对象数组。
- 项目#0:计数器:1
- 项目#0:计数器:2
- 项目#0:计数器:3
- 项目1:计数器:4
- 项目1:计数器:5
- 第1项:计数器:6
- 第2项:计数器:7
- 第2项:计数器:8
- 第2项:计数器:9
- 项目#0:计数器:7
- 项目#0:计数器:8
- 项目#0:计数器:9
- 第1项:计数器:7
- 项目1:计数器:8
- 第1项:计数器:9
- 第2项:计数器:7
- 第2项:计数器:8
- 第2项:计数器:9
以某种方式将 ItemObj.myData 的较早版本替换为较新的记录。
为什么会发生这种情况,更重要的是,如何避免这种情况并获得预期的结果?
const NUMBER_OF_ITEMS = 3;
const ARRAY_OF_OBJ = [{"id": 1,"color": "red"},{"id": 2,"color": "green"},{"id": 3,"color": "blue"}];
let GLOBAL_COUNTER = 0;
class Itemmanager{
constructor(){
this.Items = [];
for(let i = 0; i < NUMBER_OF_ITEMS; i++){
this.Items.push(new ItemObj(i));
}
}
}
class ItemObj{
constructor(identifier){
this.id = identifier;
this.myData = [];
this.getValues();
}
getValues (){
for(let i = 0; i < ARRAY_OF_OBJ.length; i++ ){
let myObj = Object.assign(ARRAY_OF_OBJ[i]);
GLOBAL_COUNTER++;
myObj.counter = GLOBAL_COUNTER;
this.myData.push(myObj);
}
}
}
// Instantiate and display
const IM = new Itemmanager();
for(let Item of IM.Items){
for(let data of Item.myData){
$("#output").append(`<li style="color: ${data.color}">Item #${Item.id}: Counter: ${data.counter} </li>`);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
<ul id="output"></ul>
</div>
解决方法
从ARRAY_OF_OBJ
数组中的3个对象开始,每当调用getValues
时,它们都会被多次引用:
let myObj = Object.assign(ARRAY_OF_OBJ[i]);
但是您仍然只有3个对象。 myObj
只是指向这三个对象之一。
将单个对象传递给Object.assign
会得到相同的对象-它不会克隆它:
const obj = {};
const obj2 = Object.assign(obj);
console.log(obj === obj2);
您需要克隆从数组中检索到的对象,否则到最后内存中仍然只有3个对象:
let myObj = { ...ARRAY_OF_OBJ[i] };
const NUMBER_OF_ITEMS = 3;
const ARRAY_OF_OBJ = [{
"id": 1,"color": "red"
},{
"id": 2,"color": "green"
},{
"id": 3,"color": "blue"
}];
let GLOBAL_COUNTER = 0;
class ItemManager {
constructor() {
this.Items = [];
for (let i = 0; i < NUMBER_OF_ITEMS; i++) {
this.Items.push(new ItemObj(i));
}
}
}
class ItemObj {
constructor(identifier) {
this.id = identifier;
this.myData = [];
this.getValues();
}
getValues() {
for (let i = 0; i < ARRAY_OF_OBJ.length; i++) {
let myObj = { ...ARRAY_OF_OBJ[i]
};
GLOBAL_COUNTER++;
myObj.counter = GLOBAL_COUNTER;
this.myData.push(myObj);
}
}
}
// Instantiate and display
const IM = new ItemManager();
for (let Item of IM.Items) {
for (let data of Item.myData) {
$("#output").append(`<li style="color: ${data.color}">Item #${Item.id}: Counter: ${data.counter} </li>`);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<ul id="output"></ul>
</div>
,
使用
let myObj = Object.assign({},ARRAY_OF_OBJ[i]);
代替
let myObj = Object.assign(ARRAY_OF_OBJ[i]);
as Object.assign()
将引用相同的对象。提供空对象作为第一个参数会创建一个新对象,并将第二个参数给定的对象复制到该对象。
但是请记住,它仍然是一个浅表副本;嵌套对象仍将存储为引用。
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div >
<ul id="output"></ul>
</div>
<script>
const NUMBER_OF_ITEMS = 3;
const ARRAY_OF_OBJ = [{"id": 1,"color": "red"},{"id": 2,"color": "green"},{"id": 3,"color": "blue"}];
let GLOBAL_COUNTER = 0;
class ItemManager{
constructor(){
this.Items = [];
for(let i = 0; i < NUMBER_OF_ITEMS; i++){
this.Items.push(new ItemObj(i));
}
}
}
class ItemObj{
constructor(identifier){
this.id = identifier;
this.myData = [];
this.getValues();
}
getValues (){
for(let i = 0; i < ARRAY_OF_OBJ.length; i++ ){
let myObj = Object.assign({},ARRAY_OF_OBJ[i]);
GLOBAL_COUNTER++;
myObj.counter = GLOBAL_COUNTER;
this.myData.push(myObj);
}
}
}
// Instantiate and display
const IM = new ItemManager();
for(let Item of IM.Items){
for(let data of Item.myData){
$("#output").append(`<li style="color: ${data.color}">Item #${Item.id}: Counter: ${data.counter} </li>`);
}
}
</script>
</body>
</html>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。