How Passing Arguments Works - Value vs Reference
In this lecture, I want to quickly talk about how exactly it works to pass arguments into functions. And this goes back to the lecture that we had about primitives versus objects, which, remember, we also call primitive types and reference types.
So this is a review of that lecture but applied to functions because we must understand how primitives and objects work in the context of functions. Let's start with a quick and simple example.
Consider the below code were we have a flight number, a passenger and a check-in function.
const flightNumber = "AH-1234";
const passenger = {
name: "John Doe",
passportNumber: 123456789
}
const checkIn = function(flightNumberParam, passengerParam) {
//...
}
checkIn(flightNumber, passenger);
Now, let's say for some reason the flight number and the passenger's name were updated in the checkIn
function.
const checkIn = function(flightNumberParam, passengerParam) {
/**
* Note that it is not a good practice to update functions parameters.
* This is just for the purpose of this lecture.
*/
flightNumberParam = "AH-5678";
passengerParam.name = "Mr. " + passengerParam.name;
// Let's do some checking here on the passport number.
// Will make sense by the end of this lecture. 😉
if (passengerParam.passportNumber === 123456789) {
console.log("Welcome, " , passengerParam.name);
} else {
console.log("You are not allowed to enter the plane.");
}
}
Let's now log both the flight number and passenger object after calling the checkIn
function.
const checkIn = function(flightNumberParam, passengerParam) {
//...
}
checkIn(flightNumber, passenger);
console.log(flightNumber);
console.log(passenger);
From th above result you can see that that the flight number hasn't changed, but the passenger's name has. You were certainly expecting this result because we have seen this happening sometimes before, but let's analyze it anyway.
The flightNumber
variable is a primitive type. As we pass it into the checkIn
function, the flightNumberParam
variable is a copy of the original value. Hence making it a completely different variable; that's why changing the value of the flightNumberParam
variable won't change the value of the flightNumber
variable.
On the other hand, when we pass the passenger
object into the checkIn
function, the passengerParam
variable is a reference to the original object in the memory heap. Hence, changing the value of the passengerParam
variable will change the value of the passenger
object.
The fact that objects behave this way when passed to functions, can have unforseeable consequences in larger code bases. That's especially true when you work with multiple developers. Let's write another quick function to show you what can happen.
const createNewPassportNumber = function(passenger) {
passenger.passportNumber = Math.trunc(Math.random() * 1000000000);
}
Let's say that our passenger first booked the flight with his original passport number. So that's the passport number that the checkIn
function will use to compare the passenger's passport number to. Reason why we hardcoded the passport number.
const checkIn = function(flightNumberParam, passengerParam) {
//...
if (passengerParam.passportNumber === 123456789) {
console.log("Welcome, " , passengerParam.name);
} else {
console.log("You are not allowed to enter the plane.");
}
}
Let's now see what happens when we change the passenger's passport number by calling the createNewPassportNumber
function and then calling the checkIn
function again.
createNewPassportNumber(passenger);
checkIn(flightNumber, passenger);
From the above result the first log Welcome, Mr. John Doe
comes from the first call to the checkIn
function. Then still from the above result, the third log says You are not allowed to enter the plane.
. This is because, we now have two functions manipulating the same object. Thus, creating a problem.
To finish, in programming, there are two terms that are used all the time when dealing with functions.: Passing By Value and Passing By Reference. And many experienced programmers that are new to JavaScript have some confusions between these terms and how it works in JavaScript. Hence I want to quickly address that here as well.
Javascript DOES NOT HAVE PASSING BY REFERENCE. It only has PASSING BY VALUE eventhough it looks like it is passing by reference. There are languages like C++ were you can pass a reference to any variable instead of the value itself. This works even with primitives. That is you could pass a reference to the value of five, and then the original value outside of the function, would be changed. And this is called pass by reference. If you already know some programming, but are new to JavaScript, be sure to understand this. I know it might feel confusing, because as we just learned, for objects, we do in fact pass in a reference .i.e the memory address of the object.
Howerver, that reference itself is still a value. It's simply a value that contains a memory address. So basically we pass a reference to the function, but we do not pass by reference and this is an important distinction.
Once again, I'm telling you this because there seems to be a lot of confusion going on about this topic among some JavaScript beginners, and especially when they come from other languages, such as C++.