For a long time I thought primitive types are shared by value and objects are shared by reference in javascript. Today I learned however that javascript always pass by value (According to the ECMAScript specification), both primitive types and objects. However when passing objects the value that is being passed is the reference.This behaviour is known as 'call by sharing' and NOT pass by reference. let's see why...
Call by Sharing: How JavaScript Passes Objects
Let's first see how primitive values are passed.
Consider the below code:
function setName(copyOfName){
copyOfName = "John";
}
let name ="Della";
setName(name);
console.log(name);// "Della"
It's pretty straightforward and easy to understand why primitive types are passed by value. Here we are passing the argument, 'name' that is assigned to the parameter, 'copyOfName'. That is, copyOfName now contains a copy of the variable, name, which has the value "Della". and reassigning copyOfName to "John" only affect this copy not the original name variable.
Now what if we were passing an object?
consider the below code:
function setPerson(copyOfPerson){
copyOfPerson.name = "John"; // here we are MUTATING
}
let person = {
name: "Della",
}
setPerson(person);
console.log(person); // { name: "John" }
Here we have an object person with name as "Della" which we are passing to the function's parameter, copyOfPerson by pass by value. But the value passed here is a copy of the reference. Hence both copyOfPerson and name point to the same object. Therefore, any modification or mutation (NOTE, I am mutating the object NOT re-assigning! - Big Difference) to the copy affects the original object since both point to the same object. That is why person becomes { name: "John" } when copyOfPerson is modified.
Now you might ask - isn't this what is known as 'Pass by Reference' ?!
Well...not really. The above code works the way it works fundamentally because an object variable contains a reference value.That reference value is itself the value stored in the variable. So technically, the reference is the value! And that's why we say javascript passes reference by value.
To prove programmatically, let's consider the below code, where we try to 're-assign' the copy.
function setPerson(copyOfPerson){
copyOfPerson = {
name: "John",
}// here we are RE-ASSIGNING
}
let person = {
name: "Della",
}
setPerson(person);
console.log(person); // { name: "Della" }
If the object was truly passed by reference, even reassigning would change the original object. However that is not the case. Here, local rebinding happens. a new object is created and it's reference is assigned to copyOfPerson. Therefore it no longer points to person and that is why person remains same ,{ name: "Della" }. This is called 'call by sharing' also known as 'call by object sharing'
To recap, JavaScript is a pass-by-value language. However, when passing objects, the value being passed is the reference to the object. This behaviour is known as call-by-sharing. In call-by-sharing, when an object is passed to a function, a copy of the reference is created and thus objects are shared. However, variable binding is not shared. So mutating the parameter modifies the original object but reassigning the parameter does not affect the original object.
Happy learning! cheers ✨
Top comments (1)
Day #2