This post is originally written here along with code snippets -> https://easyontheweb.com/passing-by-value-vs-passing-by-reference-in-javascript/
One of the most important concepts in programming where many of the new programmers and sometimes even experienced programmers make mistakes is the concept of passing by value and passing by reference. In this article we will see how passing by value and passing by reference works in javascript and why it might be a cause of a lot of bugs if not taken proper care of.
First of all, I’m lucky enough to have learned C as my first programming language as there the concepts of memory allocation and memory addresses and all play a lot more significant role in coding than say a language like Javascript. But that does not mean you should not pay attention to it in JS because as I said more often than not – it is a significant contributor to bugs in our code.
What is referencing ?
Before diving into passing by referencing I think it is only logical if we discuss what referencing actually is.
Whenever we declare variables or constants for that matter (lets call them placeholders), so whenever we declare these placeholders in Javascript and assign them a value, that placeholder could be holding one of two things -> Either it holds the value itself or in some cases it holds the reference to that value.
Holding a reference to a value means that the placeholder does not hold the value itself but holds the location in memory where that value is written. Now, whether the placeholder will contain the value or contain the reference to that value depends on what data type we assigned to the placeholder.
If you do not know, there are two kinds of data types -> primitive data types like Strings, Numbers, Booleans etc and non-primitive data types like arrays, objects , functions etc.
The difference between primitive and non-primitive data types is that primitive data types cannot be broken down into simpler types whereas non-primitive data types can. We may break an array of strings as different strings right? I hope you get the point.
All the data-types that are primitive are held by value by the placeholders they are assigned to whereas all the non-primitive data types are held by reference by their placeholders. Let us see how we can see this difference in code. Run the following code in your console and see the outputs :-
If you ran this code in your console you might have seen the outputs and wondered. As we can see that string1 was considered equal to string2 but arr1 was not considered equal to arr2. Why might that be? That is because of holding the value and holding the reference. As I explained earlier the placeholders string1 and string2 hold the value “Amit” and hence are equal whereas arr1 and arr2 do not hold by value, but instead hold by reference different memory locations and thus are not equal even if the value written on those memory locations is the same.
This simple test makes it clear that the mechanism of holding values in placeholders varies significantly between primitive and non-primitive data types.
Mutation due to referencing
Let us now explore the problem that you might face when you don’t take care of referencing while coding. As told before data types like objects and arrays etc are held by reference in placeholders so what this sometimes does is create a confusion. Let us see how :-
What just happened there ? What happened was that array2 was assigned array1 but instead of the value being assigned to array2, the same reference to the memory location was assigned to array2. Now, think about it, none of array1 and array2 contain the actual array – both of them actually contain reference to a memory location where that array exists.
When we push into array2 we are actually pushing into the array that exists at the memory location array2 is pointing at. And because it is the same location that array1 is pointing at – that is why when we console log array2 later, even that has been changed.
This is something that needs to be taken care of a lot. If you assign your object to some other variable, it still is referencing the same object – so do not by mistake mutate the object thinking that the first placeholder still has the original object’s state intact, because that has been mutated as well.
I see a similar mistake a lot of times from people , it is when they pass the object as an argument to a function and then in that function they mutate the object thinking that the object is mutated only in the local scope of that function – but this again is wrong. Even the parameter is referencing the same memory location and hence, if we mutate it, we mutate the original object itself (even outside the scope of that function).
Let us see this with an example as well :-
Just try this code out and see how obj1 has changed even outside the scope of the function. This is again, one of the places where I see a lot of people making mistakes – assuming that the object (by object I mean any non-primitive data type) won’t be changed due to mutation inside the function.
One of the ways to not make this mistake is by making a copy of every object received into your function and then make the changes on that copy – this way you would not mutate the actual object. It is fairly easy to make the copy of objects using the spread operator writing something like let copyObj = {...obj1} . You make your changes to this copyObj then.
Passing by value and passing by reference in javascript
Till now in this article we learnt about how placeholders hold static data types by value and non-static data types by reference and also how mutation works for these two. We also saw how non-static data types get mutated even inside other functions. This is exactly what passing by reference means.
When we say something is passed by value what we actually mean is that the parameter passed into the function is actually carrying a value (like a number or string) and when we say that a parameter is passed by reference what we mean is that the parameter passed into the function is not carrying an actual value but the reference (memory location) to a value.
Hence, you must have figured out by now that if we change a parameter that has been passed by value, the placeholder outside the function does not change, whereas in the case of a parameter that gets passed by reference can be mutated. Let us see one last example of what I mean to say :-
Running this code will surely give you a clearer idea on how the parameters are passed into functions in Javascript.
In certain languages like C however you can choose to pass by reference or pass by value as per your choice. If anyone wants to learn more about that you can perhaps check this article out -> https://dev.to/mikkel250/passing-by-value-passing-by-reference-in-c-1acg but in Javascript you cannot control it yourself, Javascript does it for you and you cannot override it.
I hope this article gave you more clarity about passing by value and passing by reference in javascript and will prevent you from some bugs that might have crept into your apps due to this.
If you want to learn in depth about the ternary operator in Javascript you can check this article of mine out -> https://easyontheweb.com/the-ternary-operator-in-javascript-with-examples/
Top comments (0)