Objects Are passed by Reference is Confuses me

" Objects are passed by reference . This means when we pass a variable assigned to an object into a function as an argument, the computer interprets the parameter name as pointing to the space in memory holding that object. As a result, functions which change object properties actually mutate the object permanently (even when the object is assigned to a const variable)."

Can someone please explain this to me? I read the description but do not understand clearly.

3 Likes

Say we define an array,

const arr = [1, 2, 3, 4, 5]

The variable is declared as a constant which means it cannot be reassigned.

arr = []
TypeError: Assignment to constant variable.

However, we can still mutate the array; that is, change, add or remove values. We refer to those contained values by reference to the array which is indexed. By that index we reach the value we seek.

When we pass arr to a function, we are only telling the function where the array lives in the namespace. Just as we can access and mutate the values as mentioned above, it is the same array that is seen from inside the function.

const double_values = function (s) {
  for (let x = 0; x < s.length; x++) {
    s[x] *= 2
  }
}

Notice there is no return. Let’s run this with arr.

double_value(arr)  // < arr is passed by reference only
console.log(arr)
[ 2, 4, 6, 8, 10 ]

It works this way because s is a reference to the array, arr since that is all that was passed into the function, the reference.

2 Likes

Don’t worry we all found this confusing at first and I suffered a lot in the beginning until I understood these terms well, so I will try to do my best to explain these concepts so you don’t suffer like me. :smiley:

To understand this well you need to know how exactly equal sign “=” is working in JS and then you will need to know the difference between Primitive and Object data types in JS.

Let’s start with "=":
In Js, equal sign “=” is making the variable on the left-hand side refer to the value on the right-hand side. what does that mean? let me try to explain it with an example:
let x = 10 here JS stored 10 in the memory and gave its address to x so now x is referring to 10 and this statement is called Assignment.

Assignments never copy data

let x = 6
let y = x

Here you haven’t copied the value of x (6) to y you’ve only made y referring to the same value with x which is 6 here. now you have two variables referring to the same value.

Reassignment isn’t changing the old value

let name = "myName" 
name = "anotherName"

Here you may think you’ve changed “myName” to “anotherName” but you didn’t, you only made the variable name leave “myName” and referring to another value “anotherName”.

so what happened to “myName”?
-well “myName” now is an orphan value because there are no variables are referring to it and sure you lost your access to it. and I’m not sure if there is a garbage collection for primitive data types in JS or not, it’s not our topic now.

Passing values to a function is an assignment statement!

function sum(x, y) {
  return x + y;
}
let num1 = 5;
let num2 = 10;

sum(num1, num2); // returns 15

In this line sum(num1, num2) you exactly saying execute the sum function after making x=num1 and y=num2.
This point is important and we will back to it later.
“=================================================================”
“=================================================================”

Primitive vs Object
Now let’s understand the difference between [primitive and object] data types.

There are two types of data in JS : Primitive and Objects:

Primitive: Numbers, Strings, Booleans, Symbols, Undefined…etc.
Objects:Arrays [] , Objects {}, Functions…etc.

-Mutable vs Immutable:
Primitive data types are immutable which means you can’t change their values.
ex:
let x = 5
5 here is a number so it’s immutable and you can’t change it to 6 for example.
And don’t forget if we say: x = 6 we aren’t changing 5 to 6 we only make x referring to another value and leave 5.
“=================================================================”

Objects are mutable which means you are able to change their values.

but if “=” isn’t changing values how can I change values then?
-you can do it by using their available methods and this is possible in Objects data types only.
ex:

let nums = [1, 2, 3]
nums.push(4)
// nums now is [1, 2, 3, 4]

Great! you have successfully changed the value of nums by using one of its methods “push”.

Changing the value of an Object is available through any of its variables

let names = ["Hossam", "Okasha"]
let x = names;
x.push("New Name");

console.log(names);  
console.log(x); 
// They both will be ["Hossam", "Okasha", "New Name"]. 

As you can see when you change the value with x, the name variable saw the change too, that’s because they both referring to the same value and they both are able to change it through any of its methods ONLY.
“===========================================================”
Finally let’s explain this line:

“Objects are passed” as I mentioned above Passing values to a function is an assignment statement!, and also we now know Changing the value of an Object is available through any of its variables.

So when you are passing an Object like an array to the function you are making the function parameter refer to the same array (Assignment statement) and again for the last time, I promise xD.

Object like an array is mutable so you can change its value using its methods which are available through all of the variables referring to it and when you passed the array to the function the function parameter is referring to the array now so now the function is able to change the main array.

but if you are passing a primitive data type like numbers, the function parameter will also refer to it because it’s an assignment statement BUT it will not be able to change it because it is immutable so we can say
primitive types are passing by values and Objects are passing by reference.

5 Likes

This answer is amazing. Including the first one. Still get a little confused if I walk away from the computer for a minute and then come back, then I have to reread this to refresh my memory. Thanks!

1 Like

Please, let me know if it still not clear, I’ll try to do my best to explain it more.

2 Likes

Is that even possible?

2 Likes

I was going to try to explain in detail how “pointers” work, because thinking of variables in JS in terms of references(pointers) is really making everything clear!
and I deeply want to thank you sir because I learned that from you :sweat_smile:

2 Likes

Please, do go into detail about pointers. It’s high time we had something to refer to. Make it good!

1 Like

but if you are passing a primitive data type like numbers, the function parameter will also refer to it because it’s an assignment statement BUT it will not be able to change it because it is immutable so we can say
primitive types are passing by values and Objects are passing by reference .

But that is incorrect. Everything is passed by value, it’s just the value is a reference. Don’t confuse reference/value type and their behaviour with pass by reference/value behaviour.

I kind of explained it here:

2 Likes

you are right and this line sums up a lot “the value is a reference”.
And thanks for alerting me, the expression betrayed me I just thought we could say passing by values/references to simplify it but it seems to make it more confusing in JS.

1 Like