In JavaScript we have two types of values (not everything is an Object).
Primitives
Numbers / BigInt
Strings
Symbol
Boolean
Undefined
Null
Objects
Arrays
Functions
Objects
Dates
Wrappers for Numbers, Strings, Booleans
It is natural to call numbers etc as primitive types while objects, arrays etc as reference types.
Primitives are stored in the call stack. It runs when the EC runs. References are stored in the call heap.
When we call a primitive:
JavaScript begins the EC in the call stack, by giving a memory address and also a value.
When we declare a variable as an object, the identifier is created which points to a piece of memory in the call stack which then references to a memory in the heap.
This is because the stack might be memory limited. As such, the object stored in the heap can be changed but the address in the call stack remains the same. This is because the memory address does not change!
In case of passing primitive type (e.g. a string or a number) to the function, the argument is a copy of the variable value, and not the original variable.
But, when a reference type is passed (e.g. an object or an array), the argument is a reference to the object in the memory heap.
So, it works just same as copying the variable outside of the function.
JavaScript does not having passing by references, only passing by value, even in reference types case, in which it passes a value to the reference and not the reference itself.
const flight = "LH234";const jonas = { name: "Jonas Schmedtmann", passport: 24739479284,};const checkIn = function (flightNum, passenger) { flightNum = "LH999"; passenger.name = "Mr. " + passenger.name; if (passenger.passport === 24739479284) { alert("Checked in"); } else { alert("Wrong passport!"); }};checkIn(flight, jonas);// jonas object name was modified by the function, while the flight string didn't.console.log(flight); // 'LH234'console.log(jonas); // {name: 'Mr. Jonas Schmedtmann', passport: 24739479284}