最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Array.push modify existing elements - Stack Overflow

programmeradmin2浏览0评论

I am working on a small personal project and I ran over something that I don't understand and I am hoping if someone can explain it to me. One of the methods in my module is SaveSet() which takes an array and adds it to a different array as an element so it bee two dimensional array here is the code for the SaveSet():

function SaveSet() {
    anim.push(set)
}  

When I run this code I expect it to take whatever is in the set array and adds it to the anim array as an element like this.

Set = [1,2,3,4]
SaveSet()
Set = [3,4,5,6]
SaveSet()

and I should end up with something like this:

[
   [1,2,3,4]
   [3,4,5,6]
]

However, my SaveSet() is modifying the existing one and adding a new one so I end up with something like this

[
  [1,2,3,4,3,4,5,6]
  [1,2,3,4,3,4,5,6]
]

I found a work around it by changing my SaveSet() to this:

function SaveSet() {
    let temp = JSON.stringify(set)
    anim.push(JSON.parse(temp));
}  

However, I still can't understand why anim.push is modifying the existing one as well. This is the full code incase if anyone wants to look at it. As I said this a personal quick project so the quality of the code and design are really low.

I am working on a small personal project and I ran over something that I don't understand and I am hoping if someone can explain it to me. One of the methods in my module is SaveSet() which takes an array and adds it to a different array as an element so it bee two dimensional array here is the code for the SaveSet():

function SaveSet() {
    anim.push(set)
}  

When I run this code I expect it to take whatever is in the set array and adds it to the anim array as an element like this.

Set = [1,2,3,4]
SaveSet()
Set = [3,4,5,6]
SaveSet()

and I should end up with something like this:

[
   [1,2,3,4]
   [3,4,5,6]
]

However, my SaveSet() is modifying the existing one and adding a new one so I end up with something like this

[
  [1,2,3,4,3,4,5,6]
  [1,2,3,4,3,4,5,6]
]

I found a work around it by changing my SaveSet() to this:

function SaveSet() {
    let temp = JSON.stringify(set)
    anim.push(JSON.parse(temp));
}  

However, I still can't understand why anim.push is modifying the existing one as well. This is the full code incase if anyone wants to look at it. As I said this a personal quick project so the quality of the code and design are really low. https://codepen.io/anon/pen/oJZeJy?editors=1111

Share Improve this question asked Dec 21, 2018 at 14:13 MohammedMohammed 3524 silver badges18 bronze badges 9
  • The sample code in your question does not reflect accurately the actual code int the codepen. – Pointy Commented Dec 21, 2018 at 14:21
  • 6 Set is a built in collection in JS (like a mathematical set). Don't use it as a variable name. Also don't see why you are using a function at all since you're referencing a global. – Jared Smith Commented Dec 21, 2018 at 14:25
  • Something like function saveSet( ary, addition ) { ary.push( addition); return ary; } will go a long way with avoiding such issues in code logic, since it requires you to explicitly send it the array to change and the array to add. You'll have to read a bit about object references and such if you want a thorough explanation. – Shilly Commented Dec 21, 2018 at 14:26
  • @JaredSmith I wrote this code really fast I am not sure why :D. it's true it's a bad practice but I don't think changing it will solve the issue. – Mohammed Commented Dec 21, 2018 at 14:33
  • As @Shilly said with current practices I wouldn't run into such an issue but I am still interested in why this is happening. I would think array.push will add a new element and keep the old ones untouched but that is not the case here. – Mohammed Commented Dec 21, 2018 at 14:33
 |  Show 4 more ments

3 Answers 3

Reset to default 6

You are always using the same array for all of your data.

What is happening is that you're initializing a set = [] once globally in your code.

Then each time you save a set, you are adding this array into the anim array but you never update what the variable set is pointing to.

So you just keep adding the same set array over and over:

var set = [];
var anim = [];

function addToSet() {
  set.push(String(Math.random()).slice(2,3));
  console.log(set);
}

function saveSet() {
  anim.push(set); // <--- you are always pushing the same array
  console.log(anim);
}
<button id="add" onclick="addToSet()">Add to set</button>
<button id="save" onclick="saveSet()">Save set</button>

Each time you save a set you should create a new set:

function saveSet() {
  anim.push(set);
  set = []; // <---- reset the set to a new array
}

With using .push method, you are pushing a pointer into your array. If you change your code to

function SaveSet() {
    anim.push([...set])
}  

it'll create a new array, spread current elements of set and push them to anim.

Your set array is probably changed because of a bug in another part of the code. It's not related to here

You should do the following :

var anim = []
function SaveSet(set){
  anim.push(set);
}
var set = [1,2,3,4];
SaveSet(set);
set = [3,4,5,6];
SaveSet(set);
发布评论

评论列表(0)

  1. 暂无评论