Previously in this series, we've discussed how primitives and objects behave when we try to mutate or copy them.
Now in the final article in this series we're going to see how they behave when we pass them to functions.
Recap
First article we talked about mutability, which is changing the properties of something without changing it as a whole and we said that objects are mutable while primitives aren't, here's a quick example to demo what I've just said
Second article was all about copying, when you copy a primitive you copy its value but when you copy an object you copy its reference(its address in memory),here's another quick example:
Moving on to talk about how both primitives and objects behave when we pass them to functions as arguments but first, let's talk about functions.
functions
Starting with a really typical function, the function add
now let's walk through this code to see how javascript is run.
Two main things that a javascript engine does are storing stuff and executing orders, let's see this in action.
The javascript engine reads the code from top to bottom so in our example here the first thing it sees is this:
function add(x , y){
return x + y;
}
this is called a function declaration, when the engine see
a function declaration it saves all its code inside the global memory and it doesn't execute any of the stuff inside the function because the function hasn't been called yet(remember we're talking about the first 3 lines)
Moving on to line 4 and 5 in which variables num_1
and num_2 respectively are also stored in global memory
- in the picture above the letter f is short for the function's code
-
num_1
andnum_2
are stored to demo that the engine also saves variables not functions only
execution context
Right now we've done nothing but storing stuff in global memory, on reaching the line add(2,6)
the function add
starts to execute.
when a function is called, an execution context is created and execution context is a place in which information about the function are stored.
It stores stuff like the function's local variables, at what line the program is at the moment.
so as you see in the following picture the function add
has two local variables x
and y
and they store the numbers we provided when we call the function
currently we're inside the function body, which is the line return x+y;
the program calculates the value of x + y
which is 2 + 6
in this case and that's equal to 8
.
Then the function returns this value(8) and once we return, the function's execution context goes away it vanishes and if we called the function again a new execution context will be created and that's a rule: for every function call a new execution context is created and once we hit a return statement that execution context disappears
Note:
things stored in global memory are available everywhere in our program. On the other hand, local variables are available only inside the function
And that's it for functions in this article, there's one more thing about functions behind the scenes which is the call stack
if you want to learn about it, go watch this video or read this article
Primitives as functions arguments
consider the following example
the question is: will the values of x
and language
change ?
let's see what the console will tell us
As you can see, nothing has changed that's because when we pass a primitive to a function , we're passing a copy of its value
so num
and str
have the same values as x
and language
but they're different variables.
An important thing to note is that the values of num
and str
are changed and we can see that if we put a console.log
inside the function
call by value
when you pass a primitive to a function, its value is copied to the function argument hence the primitive and the argument have the same value but they're two different variables, that's what called call by value .
objects as functions arguments
remember that objects are stored by reference which is the memory address of the object so when you say let obj = {};
you storing the address of {}
inside obj
.
Now let's see what happens when we pass an object to a function
do you expect obj
to change or remain the same ?
well, there's only one way to find out
As our console said, obj
does change.
But what if we tried the following:
In this case nothing will change and here's the output to demo that
why is that ?
When you pass an object to a function, you are passing a copy of the reference and you can use that copy to access and modify the object but you can't change the reference using the function
call by sharing
if you pass an object to a function, you can mutate the object inside the function but you can't *reassign * it.
That's called call by sharing, many people say that objects are called by reference that's not right because call by reference means passing the reference itself and hence you can both mutate and reassign the object using the function and that's not the case in javascript.
We're passing a copy of the reference not the reference itself,
it's like primitives when we pass a copy of the value not the value itself.
Hope this makes sense for you, you can read about call by sharing using the following links:
- https://en.wikipedia.org/wiki/Evaluation_strategy#Call_by_sharing
- https://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language
- https://wafy.me/tech/2016/07/02/call-by-sharing.html
And that's it for this article and the whole series, hope you guys have enjoyed the series !
Top comments (0)