范围问题 - 在回调中更改数据正在更改更高范围

我正在构建一个小 d&d 应用程序来练习以角度传递数据组件,我遇到了一个奇怪的问题。


我从 API 调用中获取了一个“怪物”对象,然后将其填充到视图中一定次数。我正在尝试通过添加索引来更改其中一个值“名称” - 简单 - 获取“名称”添加和索引。我正在获取“名称”的值来更改它,然后将其推送到组件中保存的数组 - 一切正常。我认为对于循环的下一次迭代,原始值应该保持不变,但事实并非如此。我在这里的范围内不理解的东西。


试图只发布一些代码,因为我知道问题出在哪里,而且我知道它是一个范围问题,我只想知道为什么这是一个我不熟悉的概念。使用


export class CombatComponent implements OnInit {

  selected:number;

  monsters:any[] = []

  addedMonsters:any[] =[]


  monsterNumber:number = 0;    <----this is being passed from a form - its working


  constructor( private ms:MonsterService) { }


 <-dont want to post the entire function because this is where the issue lies ->


this.$monsterData.subscribe(data =>{

 this.currentMonster=data;


 for (let i = 0 ; i<this.monsterNumber; i++){


   let originalName = this.currentMonster.name;

   console.log(this.currentMonster.name)


   this.monsters.push(this.currentMonster)

   let newName = this.monsters[i]['name'] = this.currentMonster.name +" " + `${i+1}`

   this.monsters[i].name = newName


   console.log(this.monsters)


 }

我的问题是,在第一次迭代之后,我认为应该发生的是一个带有名称 + 索引的数组。真正发生的是第二次通过 currentMonster 的“名称”值更改为原始值 + 索引。我在这里不理解范围是什么?


月关宝盒
浏览 155回答 3
3回答

米脂

每次迭代都将相同的怪物对象推送到数组上。这会导致数组元素喜欢this.monster[1]和this.monster[2] 彼此持有相同的对象。因此,如果您更改,monster[1]您正在更改monster[2]等等(包括currentMonster因为它们都引用同一个对象)我假设您实际上是在尝试根据currentMonster属性创建新的怪物对象并尝试为它们分配新名称。//these do shallow copy of the properties//this is regular javascript might have to make//changes to fit typescript syntax//using spread operator to create new object//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntaxlet newMonster = {...this.currentMonster}//using Object.assign() to create new object//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assignlet newMonster = Object.assign({},this.currentMonster);然后只需更改适当的属性并将新对象推送到数组上。//give new monster a name&nbsp;newMonster.name = this.currentMonster.name +" " + `${i+1}`;//push the new monster on the arraythis.monsters.push(newMonster);

幕布斯7119047

当你这样做时:&nbsp;this.monsters.push(this.currentMonster)您不是将currentMonster对象的副本推送到数组,而是推送对对象的引用。在这一点上,这意味着:&nbsp;this.monsters[0] === this.currentMonster那么当你改变 name 属性时:this.monsters[i].name = newName你也在改变currentMonster.name属性您可能想要做的是创建currentMonster对象的副本并仅更改名称:this.monsters.push({&nbsp; &nbsp; &nbsp;...this.currentMonster,&nbsp; &nbsp; &nbsp;name: `${this.currentMonster.name} ${i+1}`})

HUWWW

var arr = []; // create arry&nbsp;var obj = {ima:"object"}; // create objectarr.push(obj); // pass same object 3 timesarr.push(obj);arr.push(obj);console.log(arr); // log arr&nbsp;// will print : [// {//&nbsp; /**id:2**///&nbsp; &nbsp; "ima": "changed object"//&nbsp; },//&nbsp; /**ref:2**/,//&nbsp; /**ref:2**/// ]obj.ima = "changed object"; // change the object&nbsp;console.log(arr); // log the array, notice that object inside the array will be modifiedarr[0].ima = "changed in the arr"; // then modify the object inside the arrayconsole.log(obj); // notice original object will be modified.arr.push(Object.assign({},obj)); // this is the copy or use ... operator in typescriptconsole.log(obj);arr[1].ima = "something newer";console.log(obj); // "remains same"上面的代码与您在代码中所做的相同。您传递的是引用而不是复制的值。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript