-4

I like to think I have and understanding of reference types, but I am wondering what I am missing here, what is happening under the hood.

let o = {
   foo: 'bar'
};

console.log(o) // logs the object.

let p = o; // assigns reference to object

I have seen this a thousand times and move on without a thought, but this time it gave me an unexpected psychedelic jolt.

In both cases my mind reads this as 'read the value of o and'. However, one will log the actual data stored whereas the other will return a reference. What step am I missing that makes these two lines differ?

  • is let p = o; how things normally work, but console.log(o) is causing some type of implicit / default call.

  • Or is it the inverse, that o will naturally pull the actual object from the heap but an assignment will by nature always assign the reference?

"when x JavaScript will z"

Can someone explain the workings of this so I understand the exact why of it?

  • What makes you think those two examples are any different? Both the assignment and the argument are references. – jonrsharpe Jul 05 '19 at 07:54

2 Answers2

0

If you copy the value, then you copy a reference to the object.

If you do anything else with it, then the reference is followed and the object worked with.


The value of o is a reference to an object.

If you assign o to p then you copy that reference and p is also a reference to the object.

If you access o.foo then you follow the reference to the object and do something with the foo property of it.

If you pass o to a function, then you copy the reference to the parameter in the function. If that function then accesses paramater.foo then it follows the reference to the object and does something with the value of foo on it.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
0

In your code example, both o and p are pointers to the same underlying Javascript object.

When you do this:

let o = {
   foo: 'bar'
};

o contains a pointer to a Javascript object. It's important to not think of o as containing the object itself. It contains a pointer to the object and the object exists independent of either variable itself. I'm purposely not calling it a "reference" to the object because it doesn't behave fully like a reference. If I assign something else to p, that doesn't change o in any way (thus it's not a full reference). It behaves like a pointer would in a language like C.

When you assign such a pointer as in:

let p = o;

Javascript makes a copy of the pointer from o and puts it into the p variable. Each variable o and p now contains a pointer to the same object. If you modify the object via either the o or p pointer, there's only one object that each points to so you will see the modification no matter which variable you use to look at the underlying object.

// create an object and assign a pointer to that object to the variable o
let o = {
   foo: 'bar'
};

// assign a pointer to the same object to the variable p
let p = o;

// modify the object pointed to by o
o.foo = 'hello';

// since both variables point to the same object, both see the modification
console.log(o.foo);    // 'hello'
console.log(p.foo);    // 'hello'

Both o and p point to the same underlying object. Thus modifying that object, no matter which pointer you use to modify it will modify the underlying object and both pointers will still be pointing to the same (now modified) object.

p is not a reference of o because if I assign something else to p, it does not affect o at all.

let o = {
   foo: 'bar'
};
let p = o;
o.foo = 'hello';
p = {foo: 'goodbye'};   // assign different object to p
console.log(o.foo);     // o not affected by assignment of different pointer to p

When you pass that pointer to a function as in:

console.log(o);

It again makes a copy of that pointer (not a copy of the object) and passes it as an argument to the function. It is then up to the function you call to decide what to do with the argument you passed it. In this case, console.log() looks at the type of the argument, finds it is a pointer to an object and then decides to use the code it has for outputting the contents of an object. It is the inner workings of console.log() that analyzes the type of the argument and decides what to do with it.

Passing an object to a function in Javascript is just like assigning that object to another variable and in fact, that's what Javascript is doing. It is creating a new temporary variable scoped to that function and assigning a copy of the pointer to that object and then making that named parameter variable available inside the scope of the function. The function can then access that object through its local pointer to it.

jfriend00
  • 683,504
  • 96
  • 985
  • 979