0

See the following example:

const obj = { a: {} }
let aOfObj = obj.a
console.log(obj.a === aOfObj)
aOfObj.b = 4
console.log(obj.a.b === aOfObj.b)
aOfObj = {}
console.log(obj.a === aOfObj)

So aOfObj is a reference to obj.a. Setting aOfObj.b to 4 proves that. The original object's obj.a.b has been modified as well. So why setting aOfObj = {} isn't the same as if I'd set obj.a = {}?

Gergő Horváth
  • 3,195
  • 4
  • 28
  • 64
  • 2
    For that you would need what is called a double pointer in C++ – Emanuel Vintilă Nov 07 '20 at 12:56
  • 1
    Because you changed what aOfObj references, you didn’t change what obj.a references—that still references the previous object. – Dave Newton Nov 07 '20 at 12:57
  • 1
    _"So `aOfObj` is a reference to `obj.a`"_ - `aOfObj` stores the "address" where `obj.a` can be found in the memory. _"So why setting `aOfObj = {}` ..."_ - This just stores another address in `aOfObj`. – Andreas Nov 07 '20 at 13:02
  • 2
    That works quite the same way than doing `foo = 0; foo = 42;` you are **not** changing 0 to 42, but you are changing the content of the variable `foo` – Cid Nov 07 '20 at 13:09

1 Answers1

2

Each rectangle in the following diagrams denotes an object.

const obj = { a: {} } is creating the object { a: {} } in memory and assigns its reference to the variable obj.

const obj = { a: {} }

let aOfObj = obj.a is assigning the reference of the inner object a to the variable aOfObj.

let aOfObj = obj.a

Since aOfObj and obj.a are referencing the same object, altering the object referenced by aOfObj will be reflected on obj.a too, because they are the same object.

aOfObj.b = 4

Now when you do aOfObj = {}, you are creating a new object (in memory) and assigning its reference to aOfObj, so obj.a and aOfObj points to different objects.

aOfObj = {}

Note:

Both variables and objects are stored in memory. The variables (everything on the left side above) are stored on the stack, whereas the objects (everything on the right above) are stored on the heap.

When working with primitive values (like numbers, strings, ...), the variable is stored on the stack, and its value is the primitive value itself. For example: let n = 5; is creating a variable n on the stack and sets its value to the literal number 5.

When working with objects (objects, arrays, instances of classes, ...), the variable is stored on the stack, whereas the object is stored on the heap (because the stack is smaller) and the reference (the address of that object in memory) is stored as the value of the variable on the stack. For example: let o = {} is creating the variable o on the stack and the object {} on the heap and set the value of o on the stack to the address of that object which is a number (eventually keeping the stack smaller).

In javascript, unlike some other languages, the variables themselves can't be referenced, only values that are objects can, and that's why javascript is not a pass-by-reference language.

ibrahim mahrir
  • 31,174
  • 5
  • 48
  • 73
  • Why did you re-open this question that has already been closed as dupe of the [one question](https://stackoverflow.com/questions/518000/) you're referencing in your own answer? This doesn't add anything new. And even if it did, that should have been added to the dupe target. – Andreas Nov 14 '20 at 10:56
  • @Andreas my bad. I only visited the first [dupe target](https://stackoverflow.com/q/518000/), and found out that it doesn't really answer OP's question, and the second [dupe target](https://stackoverflow.com/questions/37290747/) had a similar wording (both are about pass-by-reference which is not what OP is asking about because pass-by-reference is usually related to function calls) so I didn't bother open it. I was wrong. The second dupe target is exactly the same as OP's question. – ibrahim mahrir Nov 14 '20 at 11:46