How Passing Arguments Works_ Value vs Reference | JavaScript π₯ | Lecture 120
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
π 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.
𧩠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.
β οΈ 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
π‘Reference Types
π‘Passing by Value
π‘Passing by Reference
π‘Memory Heap
π‘Arguments
π‘Parameters
π‘Immutable
π‘Unintended Consequences
π‘Memory Address
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
In this lecture, I want to quickly talk about
how exactly it works to pass arguments into functions.
And this goes back to the video that we had
about primitives versus objects,
which, remember, we also call
primitive types and reference types.
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.
And so let's draw up a quick and simple example here.
So let's set a flight number here,
234,
and an object,
which is basically a passenger,
which in this case is me.
So name, Jonas
Schmedtmann,
and then some random passport number.
So let's say just this, and by the way,
I could have all of this code here as boilerplate already,
so in the starter files, but I strongly believe
that it's better to write the code here in a video,
because then you are forced to write the code yourself,
and second, it makes the examples
a lot easier to understand.
Anyway, I now want to create a check in function.
So, basically when the passenger has already
bought the flight and is then ready to check in
to take the flight,
and then let's say, there we need a flight number,
and then also a passenger object,
which contains data about the passenger itself.
So basically we would call this function like this.
So with the flight that we already have up here,
and the Jonas object, in this case.
Alright, so this is our flight, LH234.
And this is our passenger,
but now let's say that the number of the flight was changed.
And so that can happen in the checkIn function.
And so let's now change that flight number parameter here,
and this is usually not a good practice to do,
so you should not change the parameters of a function,
but this is just to make a point.
So let's say for some reason,
the number now changed to LH999,
and I will also change the name of the passenger,
and that's because in aviation,
usually they always add a Mr or a Mrs,
in front of the name, okay.
So let's do that, Mr,
and then just the name of the passenger.
So these are some changes that the check in function does.
And then before we check in,
it will just check if the passport number is correct.
So let's say if passenger dot passport
is equal to this one,
and let's suppose that this function
gets this data from some database,
which contains the booked flights, right,
then in this case, if the passport is correct,
then let's alert, check in,
and else,
alert,
wrong passport.
Okay, and this part here will make
a little bit more sense by the end of the lecture.
Okay?
And now what I want to do is to log both the flight
and the Jonas object to the console
after calling this checkIn function.
So, flight,
and Jonas.
Okay.
And now, as I save this, what do you think
is gonna happen to these two variables here?
Can you try to anticipate it,
based on the code that we have here?
So, anyway, let's see now, and here we get checked in,
which for now isn't really important,
but then what we get is the flight number,
which is still LH234,
so exactly as we defined it here,
even though it seems like it was redefined here,
so it really wasn't.
And then we also get the Jonas object,
but now the name is indeed changed to Mr Jonas Schmedtmann.
And so that's this change here,
that happened inside of the function, right?
So maybe you actually saw this result coming,
because we actually have seen this happening
sometimes before, but let's, anyway, analyze it.
So this flight here is a primitive type, right?
It's just a string.
And as we passed that value into the function down here,
then the flight number here is basically a copy
of that original value, right?
So flight number contains a copy,
and not simply the original value of the flight variable.
So this would be exactly the same as writing
flight number equals
flight.
And this would then also simply copy
this value to flightNum, right?
And so again,
flightNum here is a completely different variable.
And therefore, as we changed it here,
it did not get reflected in the outside flight variable.
Okay, and so it's still LH234,
so exactly for the same reason as we saw before,
in the primitives versus reference types lecture.
But now what about the Jonas object that we passed,
into the checkIn function and in that function,
it is called passenger, right?
And then we changed that passenger object here.
And as we saw then,
the Jonas object was also affected by that change.
So why did that happen?
And you might already know the answer.
So when we pass a reference type to a function,
what is copied is really just a reference
to the object in the memory heap.
So that would be exactly like doing this.
So passenger
equals
Jonas.
We can actually do this and here the same,
just to get as a reference, same as doing,
okay, and so, as you already know,
when we try to copy an object like this,
we are really only copying the reference
to that object in the memory heap,
but they both point to the same object in memory.
And so that's exactly what is also happening here,
with the Jonas object, as we pass it
into the checkIn function where it's called passenger.
So here, as we are manipulating the passenger object,
it is exactly the same as manipulating the Jonas object.
Once again, because they both are
the same object in the memory heap.
Alright, so in summary, 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.
On the other hand, 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.
Now, 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.
And that's especially true when you're working
with multiple developers.
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.
So let's just create a function called
newPassport.
It will accept any person,
and basically it will simply change
that person's passport number.
And so let's simply create a random number here,
random, and let's multiply it by some huge number,
and then this will create a number
between one and
this huge thing.
So it doesn't really matter here.
We will also know trunc, as we have used before,
just so that we get a new big number,
which will be the new passport now, right.
And so now let's call that function actually,
with the Jonas object,
now, right.
So let's say that I booked the flight
with my original passport number here.
And so that's the passport number
that the checkIn function will then compare my passport to,
that's why it's hard coded right here.
But now, again, I change my passport before I check in.
And so let's see what happens then.
So here again, we need to pass in
the flight and the passenger object.
So, let's see.
So it still says checked in here,
but that's coming from this checkIn function call, okay.
So then down here, the passport is changed,
and then there's another checkIn call.
So let's see the result of that.
And so now, indeed, it says wrong passport, alright.
And so what's happening now is that we have
two functions manipulating the same object.
And so that is creating a problem,
right?
So here the exact same thing is happening,
in the new passport function.
I'm passing in an object,
and so that object here is then called person.
And as the function manipulates that person object,
of course, it also gets reflected in Jonas.
And then as we pass that Jonas object
into the checkIn function, then, of course,
that passport is no longer the same as the original one.
So, yeah, I think this is a nice example
of seeing how the interaction of different functions
with the same object can create some issues here.
And of course, this is just a super simple example,
but I'm sure you get the point, right?
What matters is that you're aware of this issue,
and then you can be careful with it.
Let's just take out these lines of code.
Also these, these don't really matter.
Let's just make sure, and indeed, yeah,
we get the wrong passport now,
because of the new passport function down there.
Okay.
Now, just to finish, in programming,
there are two terms that are used all the time
when dealing with functions,
which is passing by value, and passing by reference,
and many experienced programmers that are new to JavaScript
have some confusion between these terms
and how it works in JavaScript.
And so I wanna quickly address that here as well.
So JavaScript does not have passing by reference,
only passing by value,
even though it looks like it's passing by reference.
So 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.
And once again,
I'm only 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++.
Browse More Related Video
5.0 / 5 (0 votes)