DEV Community

Cover image for primitives vs objects in JAVASCRIPT : Call by sharing
Anwar
Anwar

Posted on

primitives vs objects in JAVASCRIPT : Call by sharing

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

mutability example

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:
copying 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
function example
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;
}
Enter fullscreen mode Exit fullscreen mode

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

global memory
Notes:

  • in the picture above the letter f is short for the function's code
  • num_1 and num_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
execution context
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
Primitives as functions arguments
the question is: will the values of x and language change ?
let's see what the console will tell us

results

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.

memory visualization

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
example

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 .

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
objects as functions arguments
do you expect obj to change or remain the same ?
well, there's only one way to find out
result
As our console said, obj does change.
But what if we tried the following:

reassigning objects using functions

In this case nothing will change and here's the output to demo that

result

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

mutate objects with functions

reassign objects with functions

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:

And that's it for this article and the whole series, hope you guys have enjoyed the series !

Top comments (0)