0

I wanted to copy one JavaScript element from an array into another array and then edit some of its properties. the specific code I used was:

var friends=[]
var enemies=[
    {
        name: "Slime",
        health: 20,
        attack: 10,
        defense: 15,
        speed: 5,
        drops: {name: "Vial of Blood", chance: 10, type: "consumable", id: 0},
        friendable: {possible: false}
    },
    {
        name: "Bat",
        health: 15,
        attack: 5,
        defense: 10,
        speed: 20,
        drops: {name: "Speedy Vial", chance: 5, type: "consumable", id: 1},
        friendable: {possible: true, item: 0}
    }
]

function dofriend(num11,num12) {
    let protype=enemies[num12]
    sack.splice(num11,1)
    invid.splice(num11,1)
    invtype.splice(num11,1)
    friends.push(protype)
    friends[friends.length-1].drops=protype.name
    friends[friends.length-1].name=prompt("Pick a name for your friend.",protype.name)
    battlechk=false;
    document.getElementById("textbox").innerText="You befriended "+friends[friends.length-1].name+"!"
    document.getElementById("optionbox").innerHTML="<button class=\"option\" onclick=\"cancel()\">Yay!</button>"
}

What is supposed to happen is that a new element gets added to the friends array that is the same as one of the elements in the enemies array. Then the player is allowed to enter a new name for that element in the friends array. Since the drops, part of the element is no longer necessary I wanted to replace it with the original name for future use. What actually happens is that both the enemies element and the friends element get edited to be the same. I don't understand why.

There may be something else happening while I am editing stuff, but that seems unlikely. I have checked and found nothing, but if you want to take a look the full code can be found here. The files that are being used in this example are friend.js and globalvars.js. In addition, battle.js and explore.js are also involved here. battle.js leads to friend.js being called and then the friends array is used in explore.js.

I am interested in knowing how JavaScript elements behave when duplicated and if there is a way to do this without editing the element in the enemies array.

Edit: Changed every instance of JSON to JavaScript because I was wrong in thinking that this was JSON.

Fish767
  • 1
  • 7
  • Have you read about immutable objects in javascript. Since, javascript stores values other than primary datatypes as reference not the copy of the object that you are trying to create, Whenever you try to change something in your copied array it changes the original as well. You could try using spread operator that ES6 comes with and now major browsers also support them. – Dipesh Dulal Feb 08 '20 at 03:41
  • @DipeshDulal I have not read about that. I am going to look that up now. – Fish767 Feb 08 '20 at 03:42
  • The question must contain -> `Current Code`, `Current Output`, `Expected Output` and `What you tried` – Prashant Pimpale Feb 08 '20 at 03:44
  • With a single line of code, the way you could create copy is by doing `const friends = [ ...enemies ]`. – Dipesh Dulal Feb 08 '20 at 03:44
  • @DipeshDulal could I get around that by actually creating a new object that uses the old objects values for its own. For example: {name: prompt(ect), attack: enemies[num12].attack,...} – Fish767 Feb 08 '20 at 03:44
  • You mean object. You have objects in array. – Danny Fardy Jhonston Bermúdez Feb 08 '20 at 03:45
  • FYI: It is not JSON.... https://stackoverflow.com/questions/6489783/whats-the-difference-between-javascript-object-and-json-object – epascarello Feb 08 '20 at 04:11
  • @epascarello What is it? – Fish767 Feb 08 '20 at 04:13
  • https://stackoverflow.com/questions/728360/how-do-i-correctly-clone-a-javascript-object – epascarello Feb 08 '20 at 04:22

1 Answers1

-1

JavaScript objects cannot be copied. Instead, all would-be-copies link back to the original. You have to hard code a new object with the desired values so that it is not linked to the original object. For example:

let f={
     name: "namehere",
     secondAttribute: 0
}
let r={
    name: f.name,
    secondAttribute: f.secondAttribute
}

r is not linked to f even though they have the same attributes. You can edit r or f without changing the other.

Fish767
  • 1
  • 7