FAQ: Objects - Pass By Reference

Update! A friend of mine who’s a Senior JS Engineer explained this to me and I get it now.

The crucial point, for me, was understanding that when you pass an object into a function to mutate a property on it, the “object” parameter in the function declaration is what gets deferenced(behind the scenes) and replaced with a reference to the original object. THIS is what allows you to mutate the original object. If you try to reassign it yourself, all you’re doing is reassigning the object parameter; it never gets deferenced by the program and assigned to reference your original object. Still a tricky concept and an awkward explanation on my part, but I was finally able to internalize it this way.

Made a diagram in an attempt to help future people who are still stuck like me. The second purple paragraph is the key point to me, and explains an invisible step that happens on line 17, which maintains the pass-by-reference to the original object and makes the mutation possible.

1 Like

The third bullet point completely lost me. I understand that primitives are passed by value, and objects are passed by reference, but what is this talking about when it says the parameter is its own variable and it became a reference itself? I’ve not seen this stated in any other resource, and I’ve spent a whole day just on this

The point seems to be that even if you reassign obj to be a different object, it does not change spaceship.

But obj is just a placeholder no? Just like any other parameter to a function. Why is the parameter relevant now? Why does it “become a reference to the memory location of the spaceship object but not the spaceship variable”…what does that even mean?

I think that there’re making the point that
objects are passed by reference,
so obj would be a reference to spaceship,
but when you reassign obj, then you are changing what obj is a reference to,
so obj is no longer a reference to spaceship.

parameters act just like variables inside the function.

I think I finally get it now. So parameters take the same reference as their corresponding argument.

Also, this lesson was badly explained imo. It assumed the reader knows about memory allocation and under the hood workings of assigment. Not helpful at all

Can someone explain me the difference?

the question is: Write a function greenEnergy() that has an object as a parameter and sets that object’s 'Fuel Type' property to 'avocado oil' .
correct:

let greenEnergy = spaceship => {
spaceship[“Fuel Type”] = “avocado oil”
}

incorrect:

function greenEnergy(){
spaceship[‘fuel type’] = ‘avocado oil’
};
I tried use spaceship as a parameter for the function too (function greenEnergy(spaceship){}) and when i log it on the console shows the correct answer.

Note the missing parameter.

1 Like

One has "Fuel Type", the other has 'fuel type'
JavaScript is case-sensitive.

2 Likes

Pass by reference seem a very important concept to understand, but i feel not completely mastering the idea in practice. I understand the concept of pass by reference in theory. An object, array and function are non-primitive functions that don’t copy a value, instead they point to a location, where the actual value is. When you change something in a pass by reference situation, you’r changing the original value.

What i don’t understand is when i try to read what happens in practice. In the following example i don’t understand why in the following function(reAssign) it doesn’t allow it to change.

let test = {
    color: "yellow"
}

let reAssign = obj => {
    obj = {
        a: "test a",
        b: "test b"
    }
    console.log(obj)
}

reAssign(test)


console.log(test) // will return only original values

What i understand here is that when i use the assignment operator directly after obj parameter, it will not be able to change the object. Instead when i do this

let test = {
    color: "yellow"
}

let reAssign = obj => {
    obj.a = "test a",
    obj.b = "test b"
}

reAssign(test)


console.log(test) // will return object values with newly reassigned values

I don’t follow why one works and the other doesn’t.

test points to an object in memory.
When you make the function call reAssign(test), then the argument is assigned to the parameter. In your example, obj will point to the same object as test.

In version 1, within the function body, you create a new object and assign it to obj. Now obj points to a different object in memory, while test still points to the original object.

In version 2, you add key-value pairs to obj. In doing so, you aren’t creating a new object. You are modifying/mutating the same object. By modifying the object that obj is pointing toward, well that is the same object that test is pointing toward.

Array example

let a = [1, 2, 3, 4, 5];
let b = a;      // a and b point to same array
b[2] = 99;    // We modify the array
console.log(a);  // Output: [1, 2, 99, 4, 5]
console.log(b); // Output: [1, 2, 99, 4, 5]

let a = [1, 2, 3, 4, 5];
let b = a;      // a and b point to same array
b = [1, 2, 99, 4, 5];    // We aren't modifying the original array.
                        // We are creating a new array and assigning it to b.
console.log(a);  // Output: [1, 2, 3, 4, 5]   // a still points to original
console.log(b); // Output: [1, 2, 99, 4, 5] // b points to new array

1 Like

This makes sense. Now i’m aware what happens and why it doesn’t return the objects.

My two cents here as JS NOOB. Not sure if it’s a good interpretation or not.
As we are using assignment operator (=) inside a function, it’s a local scope, which differs from the global scope’s variable, so the same name is just a coincidence.
Ex:

let a = [1,2] // a stores the reference "0x01" which is the memory position for [1,2]
function reassign(array) {
array = [3,4] // this local variable is in local scope, means receive a different reference 0x02
}
reassign(a);
console.log(a); // return [1,2] as the other local "array" is out of scope.

So why can we change the value of the “a” array in a function? Because as we don’t use assignment operator, JS does not need to create a new memory reference into the local scope:

function update(array) {
array.push(3); // no assignment operator, no new local reference assigned. 
}
1 Like

Please, what does “dereferencing” mean in this context? Haven’t seen this term used in the course materials so far (haha, my browser’s dictionary doesn’t know it either).

The text describing this was not describing and annotating the code from top to bottom, that’s what threw me, not in chronological order so it didn’t help, only added confusion. I drew some arrows showing what each part of the text was referring to, it helped.

But I think they could have used a simpler example with more meaningful and concise vocabulary:

For example if you’re struggling to grasp the theory and trying to gain some info to help you piece it together —>

“tryReassignment() has no knowledge at all of the spaceship variable!” — is telling me absolutely nothing in a technical sense.

AND " even though calling console.log() on the object produced the expected result" — Did it?! Isn’t the expected result the non amended one?! (i.e. identified : false,
‘transport type’ : ‘flying’)

VERY CONFUSING LANGUAGE, VERY CARELESS WRITING FOR A TRICKY TOPIC.

1 Like

But you got it, eventually, right?

Yours truly has thousands of posts that are poorly or incorrectly worded, yet they led to something. That’s all this is really about… Leading somewhere.

Kudos for digging in and finding all the little details. The more you do that, the more we will trust your code, in future. Keep it up.

1 Like

const remotelyDisable = object => {
object.disabled = true
}

for (let crewMember in spaceship.crew) {
console.log(${spaceship.crew[crewMember].name}: ${spaceship.crew[crewMember].degree})
}

Yes got it now! I’m still rusty with arrow functions! Once I converted the arrow function :

let tryReassignment = obj => {
obj = {
identified : false,
‘transport type’ : ‘flying’

To the longer way of defining the same thing:

let tryReassignment(obj){
obj = {
identified : false,
‘transport type’ : ‘flying’

It made much more sense! Part of my frustration was my lack of understanding of arrow functions lol

1 Like