Value vs Reference - Javascript Concepts 3
This is part of a series where I try to explain through each of 33 JS Concepts.
This part corresponds to the Pass by Value vs Pass by Reference.
Before we go into JavaScript of things, let's look at what Pass by Value and Pass by Reference actually means.
Quoting this answer on stackoverflow,
-
When a parameter is passed by reference, the caller and the callee use the same variable for the parameter. If the callee modifies the parameter variable, the effect is visible to the caller's variable.
-
When a parameter is passed by value, the caller and callee have two independent variables with the same value. If the callee modifies the parameter variable, the effect is not visible to the caller.
In essence, when you are passing a variable by reference, you are allowing a function to change the variable and hence bear the weight of side effects whatever that function did to your variable.
When passing by value, you give the function much lesser control. You will take into account only what is returned by the function. They can change the variables you pass in but that will not affect your variables.
But this concept is mostly outdated today. It is taught in colleges and for introductory classes but most modern languages choose to implement this way differently. Talking about modern languages, so does JavaScript.
JavaScript implements this concept with two types of data types: Primitives and Objects.
Instead of introducing two ways of passing variables to functions, we have two types of variables. The type of variable defines whether it is passed by value or by reference.
Primitives
There are 6 primitive data types in JavaScript:
- string
- number
- boolean
- null
- undefined
- symbol
These data types are represented at the lowest level and are immutable.
Immutability means that their properties cannot be altered at run time. Like,
But I thought JavaScript did not have types
Yes, JavaScript is a loosely typed language. This still means that JavaScript has data types. But these data types are not bound to any variable.
How does this relate to Value vs Reference?
Primitives are always passed by value in the truest form.
Objects
Objects are the second kind of data type available in JavaScript.
If you are wondering where are Arrays, Maps and all those wonderful things, they are all just objects with special methods underneath.
Let's define an object named Person:
This is how the structure would look in the memory.
As you can see, { name: 'John' } is allocated a place in the memory and variable person is pointing to it.
Now, John has taken a role in life and is being reassigned.
Let us look at the memory representaion for this change:
Now, we have a second variable developer pointing at the same memory that person did.
So, let's say developer learns a new skill, he adds it to his skill array. And magically person variable would have learned this skill too. Because both these variables share the same object in memory.
What if a new person now joins the company and is also named 'John'?
So, it is not the properties that matter, it is the memory it points to.
Everything that is an object (objects, arrays, functions, maps) are passed by reference in JavaScript. Going back to our earlier crazy example,
How would I protect my objects from crazy functions?
1. Write lesser crazy functions. More Pure functions.
Pure functions are those that do not produce side effects. They interact only with their arguments and do not change them in anyway.
These functions produce result only as their return value.
But what if it is not your function? What if you are passing the object to a third party?
2. Spread it.
There is a ECMAScript Stage 4 proposal for using spread operator for objects available here. You can use it now with a Babel Plugin
What you have essentially done here is to create a shallow copy of your impObj. Now the addValue can no longer hurt it by altering it's properties. You can think of it like deploying a replica.
There is also a less fancy way of doing this with Object.assign
But as you might have figured from the word shallow there are issues with cloning like this.

By building a shallow clone we have only eliminated the possibility of crazy people meddling with the first level of your object. The levels below it are still references and can be manipulated/changed by other functions/entities.
3. Deepclone it.
The next solution is to take the object clone it and go deeper and deeper into the object, find them clone them too.
I don't know who you are, but if you are reference, I would clone you.
Luckily, there is a function to do that, cloneDeep.
Does this change the way I write code?
Well, it should. It should tell you why pure functions are so important in functional programming. It should tell you there are primitives and objects. and it should tell you how JavaScript implements Value vs Reference.
Is there something I missed? Something wrong? Something good? Ping me on Twitter