How Passing Arguments Works_ Value vs Reference | JavaScript πŸ”₯ | Lecture 120

The Coding Classroom
27 Apr 202313:37

Summary

TLDRThis lecture delves into the intricate workings of passing arguments to functions in JavaScript, revisiting the crucial concepts of primitives vs. objects (reference types). Through practical examples, it illustrates how primitives are passed by value, creating copies, while objects are passed by reference, allowing modifications to the original object. The lecturer highlights the potential pitfalls of unintended object mutations across functions, emphasizing the need for caution in large codebases, especially when working with multiple developers. Additionally, the lecture clarifies the distinction between passing by value and passing by reference in JavaScript, addressing common misconceptions among programmers transitioning from languages like C++.

Takeaways

  • πŸ”‘ Understanding how primitives and objects are passed into functions is crucial in JavaScript.
  • πŸ’» When a primitive value is passed into a function, a copy of that value is created, leaving the original value unchanged.
  • πŸ“˜ When an object is passed into a function, a reference to the object in memory is copied, not the object itself.
  • ✏️ Modifying an object parameter within a function also modifies the original object outside the function.
  • ⚠️ Carelessly modifying objects through functions can lead to unintended consequences in large codebases, especially when working with multiple developers.
  • πŸ”„ JavaScript uses pass-by-value for both primitives and objects, even though objects appear to be passed by reference.
  • 🧠 The confusion around pass-by-reference in JavaScript often stems from developers coming from languages like C++ where true pass-by-reference exists.
  • πŸ” In JavaScript, even when an object is passed, it's still a value (a memory reference) that's being passed, not the object itself by reference.
  • πŸ“ Writing code examples during lectures helps reinforce learning and understanding for students.
  • πŸ”– The lecture covers a fundamental concept (primitives vs. objects) in the context of functions, which is essential for JavaScript developers.

Q & A

  • What is the main topic discussed in this lecture?

    -The main topic discussed in this lecture is how arguments are passed into functions in JavaScript, and the difference between passing primitive types and reference types (objects).

  • What is the difference between passing a primitive type and an object to a function in JavaScript?

    -When passing a primitive type (e.g., a string or number) to a function, a copy of the value is created inside the function. Changes made to this copy inside the function do not affect the original value outside the function. However, when passing an object to a function, a reference to the object in memory is passed. Changes made to the object inside the function affect the original object outside the function.

  • Can you explain the terms 'passing by value' and 'passing by reference' in the context of JavaScript?

    -JavaScript does not have true 'passing by reference'. Instead, it uses 'passing by value', even for objects. When an object is passed to a function, the reference (memory address) of the object is passed by value, not the object itself. This reference is a value that contains the memory address of the object.

  • Why is it important to understand how arguments are passed to functions in JavaScript?

    -Understanding how arguments are passed to functions is crucial because it can have unforeseeable consequences in large codebases, especially when working with multiple developers. It helps avoid unexpected behavior and potential issues when multiple functions manipulate the same object.

  • In the provided example, what happens when the `checkIn` function changes the `flightNum` parameter?

    -When the `checkIn` function changes the `flightNum` parameter, it does not affect the original `flight` variable outside the function because `flightNum` is a copy of the primitive string value.

  • In the provided example, what happens when the `checkIn` function changes the `passenger` object?

    -When the `checkIn` function changes the `passenger` object, it affects the original `Jonas` object outside the function because they both point to the same object in memory.

  • Can you explain the potential issue demonstrated by the `newPassport` function in the example?

    -The `newPassport` function demonstrates a potential issue where multiple functions manipulate the same object. In this case, the `newPassport` function changes the passport number of the `Jonas` object, which then causes the `checkIn` function to fail because it expects the original passport number.

  • What is the purpose of using the `Math.random()` function in the `newPassport` function?

    -The `Math.random()` function is used in the `newPassport` function to generate a random new passport number for the person object passed as an argument.

  • Why does the instructor recommend writing code during the lecture instead of providing boilerplate code?

    -The instructor believes that writing code during the lecture forces the viewer to write the code themselves, which reinforces the learning process. Additionally, it makes the examples easier to understand when the code is written step-by-step.

  • What is the overall message or recommendation given by the instructor regarding passing arguments to functions in JavaScript?

    -The overall message is to be aware of how arguments are passed to functions in JavaScript and to be careful when dealing with objects, as multiple functions manipulating the same object can create unexpected issues. Understanding this behavior is crucial, especially when working on large codebases with multiple developers.

Outlines

00:00

πŸ”„ Passing Arguments into Functions

This paragraph explains how primitive types and objects (reference types) behave differently when passed as arguments to functions in JavaScript. It uses an example to demonstrate that when a primitive type (e.g., a string) is passed to a function, any changes made to the parameter inside the function do not affect the original variable outside the function. However, when an object is passed to a function, any changes made to the object inside the function are reflected in the original object outside the function. This behavior is because objects are passed by reference, meaning that the function receives a reference (memory address) to the original object, rather than a copy of the object itself.

05:02

🧩 Primitive vs. Object Behavior in Functions

This paragraph further elaborates on the behavior of primitive types and objects when passed as arguments to functions. It explains that when a primitive type is passed to a function, a copy of the value is created, so any changes made to the parameter inside the function do not affect the original variable outside. In contrast, when an object is passed to a function, a reference (memory address) to the object in the memory heap is copied. Therefore, any changes made to the object inside the function are reflected in the original object outside the function, as they both point to the same object in memory. The paragraph emphasizes the importance of understanding this behavior to avoid unforeseeable consequences, especially when working with large codebases and multiple developers.

10:04

⚠️ Potential Issues with Object Manipulation

This paragraph demonstrates a potential issue that can arise when multiple functions manipulate the same object. It introduces a new function called `newPassport` that modifies a person's passport number. When this function is called with the same object that was passed to the `checkIn` function from the previous examples, it changes the passport number, causing the `checkIn` function to fail because it compares the passport number against a hardcoded value. This scenario highlights how the interaction of different functions manipulating the same object can lead to unintended consequences and potential issues in larger codebases. The paragraph emphasizes the importance of being aware of this behavior and being careful when working with objects and functions.

Mindmap

Keywords

πŸ’‘Primitive Types

Primitive types are basic data types in JavaScript, like numbers, strings, booleans, etc. They are immutable and their values are stored directly in memory. In the video, the speaker explains that when primitive types are passed as arguments to functions, a copy of their value is created, not a reference to the original value. For example, when the flight number string is passed to the checkIn function, the function operates on a copy of the string, not the original.

πŸ’‘Reference Types

Reference types, also called objects, are more complex data structures that store collections of values. Unlike primitive types, when objects are passed as arguments to functions, only a reference (or memory address) to the original object is passed, not a copy. This means that any changes made to the object inside the function will affect the original object outside the function. The video illustrates this by showing how modifying the passenger object inside the checkIn function changes the original Jonas object.

πŸ’‘Passing by Value

Passing by value refers to the way JavaScript handles arguments when they are primitive types. A copy of the value is created and passed to the function, leaving the original value unchanged. The video explains that JavaScript only passes by value, even though it might appear to pass objects by reference. The speaker clarifies that objects are actually passed as a reference value, not by reference.

πŸ’‘Passing by Reference

Passing by reference is a concept in some programming languages where the memory address of a variable is passed to a function, rather than a copy of its value. This means that changes made to the variable inside the function will also affect the original variable outside the function. The video emphasizes that JavaScript does not have true passing by reference, even though it appears to work that way for objects.

πŸ’‘Memory Heap

The memory heap is a region of computer memory used for storing objects and other complex data structures. In the video, the speaker explains that when objects are passed to functions, a reference to the object's location in the memory heap is passed, rather than a copy of the object itself. This allows multiple references to point to the same object in the heap, which is why modifying the object inside a function affects the original object.

πŸ’‘Arguments

Arguments are the values or expressions passed to a function when it is called. The video focuses on understanding how JavaScript handles different types of arguments (primitive types and reference types) when they are passed to functions. The behavior of arguments is crucial for avoiding unintended consequences, especially when working with objects in large codebases or with multiple developers.

πŸ’‘Parameters

Parameters are the named variables defined in the function's declaration that receive the values of the arguments when the function is called. In the video, the speaker demonstrates how changing the values of parameters inside a function (like flightNum and passenger) can affect the original arguments passed to the function, depending on whether they are primitive types or reference types.

πŸ’‘Immutable

Immutable means unchangeable or unable to be modified. In the context of the video, primitive types like strings and numbers are immutable, meaning their values cannot be changed directly. Instead, when a new value is assigned to a primitive type variable, a new memory location is created with the new value. The video illustrates this by showing that changing the flightNum parameter inside the checkIn function does not affect the original flight variable outside the function.

πŸ’‘Unintended Consequences

Unintended consequences refer to unexpected or undesirable outcomes that can occur as a result of an action or decision. In the video, the speaker emphasizes the importance of understanding how JavaScript handles primitive types and reference types when passing them to functions, as failing to do so can lead to unintended consequences, especially in large codebases or when working with multiple developers. The example of the newPassport function illustrates how different functions modifying the same object can create unintended consequences.

πŸ’‘Memory Address

A memory address is a specific location in computer memory where data is stored. When objects (reference types) are passed to functions in JavaScript, the memory address of the object in the memory heap is passed, rather than a copy of the object itself. This allows multiple references to point to the same object in memory, which is why modifying the object inside a function affects the original object outside the function.

Highlights

In this lecture, I want to quickly talk about, how exactly it works to pass arguments into functions.

So this is kind of a review of that lecture, but applied to functions, because it's super important, that we really understand how primitives and objects, work in the context of functions.

When we pass a reference type to a function, what is copied is really just a reference, to the object in the memory heap.

Passing a primitive type, to a function is really just the same, as creating a copy like this, outside of the function. So the value is simply copied.

When we pass an object to a function, it is really just like copying an object like this. And so whatever we change in a copy, will also happen in the original.

Of course, we need to be careful, with this behavior and always keep it in mind. That's because the fact that objects, behave this way when passed to functions, can have unforeseeable consequences in large code bases.

So let's write another quick function here, to show you what can happen, so that you can be prepared for the real life, basically.

And so what's happening now is that we have, two functions manipulating the same object. And so that is creating a problem.

JavaScript does not have passing by reference, only passing by value, even though it looks like it's passing by reference.

There are languages like C++, where you can pass a reference to any value, instead of the value itself. This works even with primitives, so 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.

But once again, JavaScript does not have pass by reference.

So if you already know some programming, but are new to JavaScript, be sure to understand this.

And I know it's confusing, because as we just learned, for objects, we do in fact pass in a reference. So the memory address of the object.

However, 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.

Transcripts

play00:01

In this lecture, I want to quickly talk about

play00:03

how exactly it works to pass arguments into functions.

play00:08

And this goes back to the video that we had

play00:11

about primitives versus objects,

play00:14

which, remember, we also call

play00:15

primitive types and reference types.

play00:19

So this is kind of a review of that lecture,

play00:21

but applied to functions, because it's super important

play00:26

that we really understand how primitives and objects

play00:30

work in the context of functions.

play00:34

And so let's draw up a quick and simple example here.

play00:39

So let's set a flight number here,

play00:44

234,

play00:45

and an object,

play00:49

which is basically a passenger,

play00:52

which in this case is me.

play00:54

So name, Jonas

play00:59

Schmedtmann,

play01:00

and then some random passport number.

play01:05

So let's say just this, and by the way,

play01:08

I could have all of this code here as boilerplate already,

play01:12

so in the starter files, but I strongly believe

play01:15

that it's better to write the code here in a video,

play01:18

because then you are forced to write the code yourself,

play01:22

and second, it makes the examples

play01:24

a lot easier to understand.

play01:26

Anyway, I now want to create a check in function.

play01:32

So, basically when the passenger has already

play01:37

bought the flight and is then ready to check in

play01:40

to take the flight,

play01:42

and then let's say, there we need a flight number,

play01:46

and then also a passenger object,

play01:49

which contains data about the passenger itself.

play01:52

So basically we would call this function like this.

play01:59

So with the flight that we already have up here,

play02:02

and the Jonas object, in this case.

play02:06

Alright, so this is our flight, LH234.

play02:10

And this is our passenger,

play02:13

but now let's say that the number of the flight was changed.

play02:17

And so that can happen in the checkIn function.

play02:19

And so let's now change that flight number parameter here,

play02:25

and this is usually not a good practice to do,

play02:27

so you should not change the parameters of a function,

play02:31

but this is just to make a point.

play02:33

So let's say for some reason,

play02:35

the number now changed to LH999,

play02:40

and I will also change the name of the passenger,

play02:43

and that's because in aviation,

play02:45

usually they always add a Mr or a Mrs,

play02:49

in front of the name, okay.

play02:52

So let's do that, Mr,

play02:55

and then just the name of the passenger.

play02:59

So these are some changes that the check in function does.

play03:02

And then before we check in,

play03:05

it will just check if the passport number is correct.

play03:09

So let's say if passenger dot passport

play03:15

is equal to this one,

play03:18

and let's suppose that this function

play03:20

gets this data from some database,

play03:23

which contains the booked flights, right,

play03:28

then in this case, if the passport is correct,

play03:31

then let's alert, check in,

play03:36

and else,

play03:40

alert,

play03:42

wrong passport.

play03:48

Okay, and this part here will make

play03:50

a little bit more sense by the end of the lecture.

play03:53

Okay?

play03:54

And now what I want to do is to log both the flight

play03:57

and the Jonas object to the console

play04:00

after calling this checkIn function.

play04:05

So, flight,

play04:11

and Jonas.

play04:13

Okay.

play04:14

And now, as I save this, what do you think

play04:16

is gonna happen to these two variables here?

play04:20

Can you try to anticipate it,

play04:22

based on the code that we have here?

play04:24

So, anyway, let's see now, and here we get checked in,

play04:29

which for now isn't really important,

play04:32

but then what we get is the flight number,

play04:35

which is still LH234,

play04:38

so exactly as we defined it here,

play04:41

even though it seems like it was redefined here,

play04:45

so it really wasn't.

play04:47

And then we also get the Jonas object,

play04:50

but now the name is indeed changed to Mr Jonas Schmedtmann.

play04:56

And so that's this change here,

play04:58

that happened inside of the function, right?

play05:02

So maybe you actually saw this result coming,

play05:05

because we actually have seen this happening

play05:07

sometimes before, but let's, anyway, analyze it.

play05:12

So this flight here is a primitive type, right?

play05:16

It's just a string.

play05:18

And as we passed that value into the function down here,

play05:21

then the flight number here is basically a copy

play05:25

of that original value, right?

play05:27

So flight number contains a copy,

play05:30

and not simply the original value of the flight variable.

play05:34

So this would be exactly the same as writing

play05:37

flight number equals

play05:41

flight.

play05:42

And this would then also simply copy

play05:45

this value to flightNum, right?

play05:48

And so again,

play05:49

flightNum here is a completely different variable.

play05:52

And therefore, as we changed it here,

play05:55

it did not get reflected in the outside flight variable.

play05:59

Okay, and so it's still LH234,

play06:03

so exactly for the same reason as we saw before,

play06:06

in the primitives versus reference types lecture.

play06:11

But now what about the Jonas object that we passed,

play06:14

into the checkIn function and in that function,

play06:16

it is called passenger, right?

play06:19

And then we changed that passenger object here.

play06:22

And as we saw then,

play06:24

the Jonas object was also affected by that change.

play06:28

So why did that happen?

play06:30

And you might already know the answer.

play06:32

So when we pass a reference type to a function,

play06:36

what is copied is really just a reference

play06:39

to the object in the memory heap.

play06:42

So that would be exactly like doing this.

play06:46

So passenger

play06:48

equals

play06:50

Jonas.

play06:51

We can actually do this and here the same,

play06:55

just to get as a reference, same as doing,

play07:01

okay, and so, as you already know,

play07:03

when we try to copy an object like this,

play07:06

we are really only copying the reference

play07:08

to that object in the memory heap,

play07:11

but they both point to the same object in memory.

play07:14

And so that's exactly what is also happening here,

play07:17

with the Jonas object, as we pass it

play07:19

into the checkIn function where it's called passenger.

play07:23

So here, as we are manipulating the passenger object,

play07:27

it is exactly the same as manipulating the Jonas object.

play07:31

Once again, because they both are

play07:34

the same object in the memory heap.

play07:38

Alright, so in summary, passing a primitive type

play07:42

to a function is really just the same

play07:45

as creating a copy like this, outside of the function.

play07:49

So the value is simply copied.

play07:51

On the other hand, when we pass an object to a function,

play07:55

it is really just like copying an object like this.

play07:59

And so whatever we change in a copy

play08:02

will also happen in the original.

play08:04

Now, of course, we need to be careful

play08:06

with this behavior and always keep it in mind.

play08:10

That's because the fact that objects

play08:12

behave this way when passed to functions

play08:15

can have unforeseeable consequences in large code bases.

play08:20

And that's especially true when you're working

play08:22

with multiple developers.

play08:25

So let's write another quick function here

play08:27

to show you what can happen,

play08:29

so that you can be prepared for the real life, basically.

play08:34

So let's just create a function called

play08:39

newPassport.

play08:44

It will accept any person,

play08:47

and basically it will simply change

play08:49

that person's passport number.

play08:54

And so let's simply create a random number here,

play08:58

random, and let's multiply it by some huge number,

play09:03

and then this will create a number

play09:05

between one and

play09:07

this huge thing.

play09:10

So it doesn't really matter here.

play09:12

We will also know trunc, as we have used before,

play09:18

just so that we get a new big number,

play09:20

which will be the new passport now, right.

play09:24

And so now let's call that function actually,

play09:28

with the Jonas object,

play09:31

now, right.

play09:32

So let's say that I booked the flight

play09:34

with my original passport number here.

play09:37

And so that's the passport number

play09:39

that the checkIn function will then compare my passport to,

play09:43

that's why it's hard coded right here.

play09:47

But now, again, I change my passport before I check in.

play09:54

And so let's see what happens then.

play09:58

So here again, we need to pass in

play10:00

the flight and the passenger object.

play10:04

So, let's see.

play10:07

So it still says checked in here,

play10:09

but that's coming from this checkIn function call, okay.

play10:14

So then down here, the passport is changed,

play10:17

and then there's another checkIn call.

play10:19

So let's see the result of that.

play10:22

And so now, indeed, it says wrong passport, alright.

play10:27

And so what's happening now is that we have

play10:29

two functions manipulating the same object.

play10:33

And so that is creating a problem,

play10:37

right?

play10:38

So here the exact same thing is happening,

play10:40

in the new passport function.

play10:42

I'm passing in an object,

play10:44

and so that object here is then called person.

play10:47

And as the function manipulates that person object,

play10:50

of course, it also gets reflected in Jonas.

play10:54

And then as we pass that Jonas object

play10:57

into the checkIn function, then, of course,

play11:00

that passport is no longer the same as the original one.

play11:04

So, yeah, I think this is a nice example

play11:08

of seeing how the interaction of different functions

play11:11

with the same object can create some issues here.

play11:14

And of course, this is just a super simple example,

play11:18

but I'm sure you get the point, right?

play11:21

What matters is that you're aware of this issue,

play11:24

and then you can be careful with it.

play11:27

Let's just take out these lines of code.

play11:30

Also these, these don't really matter.

play11:34

Let's just make sure, and indeed, yeah,

play11:37

we get the wrong passport now,

play11:39

because of the new passport function down there.

play11:44

Okay.

play11:45

Now, just to finish, in programming,

play11:48

there are two terms that are used all the time

play11:51

when dealing with functions,

play11:53

which is passing by value, and passing by reference,

play11:57

and many experienced programmers that are new to JavaScript

play12:01

have some confusion between these terms

play12:03

and how it works in JavaScript.

play12:05

And so I wanna quickly address that here as well.

play12:08

So JavaScript does not have passing by reference,

play12:12

only passing by value,

play12:14

even though it looks like it's passing by reference.

play12:17

So there are languages like C++,

play12:21

where you can pass a reference to any value,

play12:24

instead of the value itself.

play12:27

This works even with primitives,

play12:28

so you could pass a reference to the value of five,

play12:32

and then the original value,

play12:33

outside of the function, would be changed.

play12:36

And this is called pass by reference.

play12:39

But once again, JavaScript does not have pass by reference.

play12:44

So if you already know some programming,

play12:47

but are new to JavaScript, be sure to understand this.

play12:50

And I know it's confusing, because as we just learned,

play12:54

for objects, we do in fact pass in a reference.

play12:58

So the memory address of the object.

play13:01

However, that reference itself is still a value.

play13:05

It's simply a value that contains a memory address.

play13:09

So basically we pass a reference to the function,

play13:13

but we do not pass by reference,

play13:16

and this is an important distinction.

play13:19

And once again,

play13:20

I'm only telling you this because there seems to be

play13:23

a lot of confusion going on about this topic

play13:27

among some JavaScript beginners, and especially

play13:30

when they come from other languages, such as C++.