1

An example, I declared an object json and in a for loop, I change the json's value and push it into the list2, But It didn't output the value what I expected.

var json = {
    value: '',
    text: '',
};

let list = [
    {
        a: 1,
        b: 2,
        c: 3
    },
    {
        a: 4,
        b: 5,
        c: 6
    }
];
let list2 = [];
for(i = 0; i < list.length; i++){
    json.value = list[i].a;
    json.text = list[i].b;

    list2.push(json);
}

console.log(list2)

the expected output is

list2 = [
    {
        value: 1,
        text: 2,
    },
    {
        value: 4,
        text: 5,
    }
];

but the fact is:

list2 = [
    {
        value: 4,
        text: 5,
    },
    {
        value: 4,
        text: 5,
    }
];

Why?

PS:I know how to avoid this question, But I can't understand why it happened

afraid.jpg
  • 965
  • 2
  • 14
  • 31
  • Because you're pushing the same `json` object twice to the array. Make a check: `list2[0] === list2[1]` => `true`. – Teemu Mar 16 '20 at 06:34
  • 2
    Pushing the object doesn't make a copy of it, you're pushing the same object every time. – Barmar Mar 16 '20 at 06:36
  • you could push an object in single line: `list2.push({ value: list[i].a, text: list[i].b })` – shrys Mar 16 '20 at 06:37
  • https://stackoverflow.com/questions/13104494/does-javascript-pass-by-reference – Teemu Mar 16 '20 at 06:42
  • Hello @afraid.jpg, The issue with your JSON variable which is re-assign the value with the latest value every time. you should use newly assign variable while push in array or you should directly assign inline. – ankitkanojia Mar 16 '20 at 06:42
  • @Barmar You means that `push()`'s params passing like a pointer? Every times I pushed the `json`, `list2` accepted the memory address of `json`? – afraid.jpg Mar 16 '20 at 06:46
  • Yes, all variable assignments and parameter passing in JS uses references, it doesn't make copies, analogous to pointers in C. – Barmar Mar 16 '20 at 06:48
  • There's a deep explanation: http://dmitrysoshnikov.com/ecmascript/chapter-8-evaluation-strategy/#call-by-sharing (the link found from ures6445533's answer in the post linked above). – Teemu Mar 16 '20 at 06:51

2 Answers2

2

Javascript has 5 data types that are passed by value: Boolean, null, undefined, String, and Number. Called primitive types.

Javascript has 3 data types that are passed by reference: Array, Function, and Object.

So in your case, json is an object and changing its value will be reflecting as referencial.

A variable holding an object does not "directly" hold an object. What it holds is a reference to an object. When you assign that reference from one variable to another, you're making a copy of that reference. Now both variables hold a reference to an object. Modifying the object through that reference changes it for both variables holding a reference to that object.

Although you have list array, pushing json is pushing its reference in it.

Bilal Siddiqui
  • 3,579
  • 1
  • 13
  • 20
-1

Issue with your json object which is not initialize so after iteration its having the reference to letest one value.

let list = [{
    a: 1,
    b: 2,
    c: 3
  },
  {
    a: 4,
    b: 5,
    c: 6
  }
];

let list2 = [];
for (i = 0; i < list.length; i++) {
  list2.push({
    value: list[i].a,
    text: list[i].b
  });
}

console.log(list2)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
ankitkanojia
  • 3,072
  • 4
  • 22
  • 35