1

I am struggling to understand the behavior of the following lines of code:

// I'd like to keep this value constant
let allObjects = [{value: null}, {value: 'Hello World'}]
// Here is a shorter list of objects matching some criteria
let someObjects = allObjects.filter(object => object.value)
// Here we work with the the values for some of the objects
someObjects[0].value = {hmm: 'test'}
// Kind of expecting allObjects[1].value to be 'Hello World' at this point
// Display all the objects
console.log(allObjects)

And the output:

[
  {
    "value": null
  },
  {
    "value": {
      "hmm": "test"
    }
  }
]

Here is a codepen.

What I do not understand is when the value of someObjects is modified it affects the value of allObjects and expect that allObjects[1].value will return Hello World.

Could someone explain to me why this is actually happening and how we are supposed create a sorter version of the array that does not mutate the original array when it is modified?

Craig van Tonder
  • 7,497
  • 18
  • 64
  • 109

1 Answers1

1

In JavaScript all primitive variables are passed by value however all objects are passed by a copy of its reference More Info. In your case, the array contains objects. Each index in the array contains a simple pointer to the memory location of an object. When you filter the array you are creating a new array with fewer values however the pointers are still pointing to the same internal objects. The filtered array, someObjects, contains a single pointer that points to the object { value: 'Hello World' }. You are overwriting the value property of this object with another object, { hmm: 'test' }. If you instead wanted to replace the object in the new filtered array rather than changing the value property of the old object you would do someObjects[0] = { hmm: 'test' }

const obj = { foo: 'bar' };
const copy = obj;
console.log(obj);
copy.foo = 'changed';
console.log(obj);
Nick Abbott
  • 364
  • 1
  • 9
  • No. JavaScript is never pass by reference. It's because the *value* of an object is its reference to memory. – Andrew Li Jul 10 '18 at 22:51
  • https://stackoverflow.com/questions/13104494/does-javascript-pass-by-reference JavaScript primatives (such as string, number) are pass by value. Objects (such as arrays and generic JavaScript objects) pass their reference. – Nick Abbott Jul 10 '18 at 22:53
  • 2
    I think we're saying the same thing, or I misunderstood your answer at "all objects are passed by reference". All I'm saying is that JavaScript is strictly pass-by-value, but in an object's case, its value is a reference. – Andrew Li Jul 10 '18 at 22:55