The call and apply Methods | JavaScript 🔥 | Lecture 124

The Coding Classroom
28 Apr 202316:52

Summary

TLDRIn this informative lecture, we delve into the intricacies of the 'this' keyword in JavaScript, particularly focusing on how to manually set it and understand its significance in different contexts. Using Lufthansa, the largest European airline group, as an example, we explore creating a simple booking system. We illustrate how the 'this' keyword can dynamically point to different objects, such as Lufthansa and Eurowings, to handle bookings. Through practical examples, we introduce the use of JavaScript's first-class functions and the methods 'call', 'apply', and 'bind' to explicitly set the 'this' keyword, demonstrating how to efficiently manage function contexts across different objects without duplicating code.

Takeaways

  • 📚 The 'this' keyword in JavaScript refers to the object it belongs to, and its value varies depending on how the function is called.
  • 💻 Enhanced object literal syntax allows for simpler method definitions in JavaScript objects.
  • ✈️ Example given involves creating a booking system for airlines like Lufthansa and Eurowings, demonstrating practical use of 'this'.
  • 📈 Methods within objects can access the object's properties and array of bookings using 'this' keyword.
  • ⚡️ Directly copying methods between objects is discouraged due to bad practice; instead, functions should be stored externally and reused.
  • 🔧 JavaScript's first-class functions enable the storage of functions in variables for reuse across different contexts.
  • 🔒 Regular function calls set 'this' to undefined in strict mode, illustrating the dynamic nature of 'this'.
  • 🔨 The 'call' method allows explicit setting of 'this' for a function, enabling flexibility across different objects.
  • 👨‍🔧 The 'apply' method is similar to 'call', but takes an array of arguments instead.
  • 🔫 Modern JavaScript favors the 'call' method with spread operator over 'apply' for passing an array of arguments.
  • 🔔 'bind' method offers another way to set 'this' keyword but is left for further discussion in the next lecture.

Q & A

  • What is the main topic being discussed in this lecture?

    -The main topic being discussed is how to manually set the 'this' keyword in JavaScript using the call, apply, and bind methods, and why you would want to do that.

  • Why is it considered a bad practice to copy and paste methods across different objects?

    -It is considered a bad practice because it violates the DRY (Don't Repeat Yourself) principle of programming. Instead, it's better to create a separate function that can be reused across different objects.

  • What happens when you call a regular function, and how does it affect the value of the 'this' keyword?

    -When you call a regular function (not a method), the 'this' keyword inside that function points to undefined in strict mode. This is because the function is not bound to any specific object.

  • How does the call() method allow you to manually set the 'this' keyword?

    -The call() method allows you to manually set the 'this' keyword by passing the object you want 'this' to reference as the first argument. The remaining arguments are passed to the function being called.

  • What is the difference between the call() and apply() methods?

    -The call() method accepts the arguments to be passed to the function individually, while the apply() method accepts an array of arguments to be passed to the function.

  • How can you achieve the same functionality as apply() in modern JavaScript?

    -In modern JavaScript, you can use the spread operator (...) with the call() method to spread the elements of an array as individual arguments, achieving the same functionality as apply().

  • Why is the bind() method considered more important than call() and apply()?

    -The bind() method is considered more important because it allows you to create a new function with the 'this' keyword permanently bound to a specific object, which can be useful in certain scenarios like event handlers or currying.

  • What are the property names that the 'book' method expects to exist on the airline objects?

    -The 'book' method expects the airline objects to have properties named 'airline', 'iataCode', and 'bookings'.

  • Why is it important to understand the dynamics of the 'this' keyword in JavaScript?

    -It is important to understand the dynamics of the 'this' keyword because its value can change depending on how a function is called, and understanding this behavior is crucial for writing correct and maintainable code.

  • What is the purpose of creating the 'book' function separately and assigning it to a variable?

    -The purpose of creating the 'book' function separately and assigning it to a variable is to enable code reuse across different airline objects, rather than copying and pasting the method into each object.

Outlines

00:00

🛫 Understanding the 'this' Keyword in JavaScript

This section introduces the concept of using the 'this' keyword within a JavaScript object, focusing on a simple booking system for an airline, specifically Lufthansa. The lecturer demonstrates creating an object with properties like airline name, code, and bookings array, and a booking method using enhanced object literal syntax for simplicity. The method logs booking information to the console, illustrating how the 'this' keyword refers to the object it is part of, allowing access to the object's properties and methods. This is highlighted as a review of how 'this' operates, emphasizing the importance of understanding its behavior before moving on. An example is shown where two bookings are made, reinforcing the idea that 'this' points to the Lufthansa object where the book method is called.

05:02

🔄 Reusing Functions with First-Class Functions in JavaScript

This segment explains how to avoid redundancy and bad practices, like copying and pasting methods between objects, by leveraging JavaScript's first-class functions. The instructor illustrates this by extracting the book method from the Lufthansa object and storing it in a separate, reusable function. However, a challenge arises when the 'this' keyword becomes undefined because the method is now a regular function call, not tied to any object. This issue highlights the dynamic nature of 'this' in JavaScript, depending on how a function is called, and sets the stage for discussing solutions to explicitly set the 'this' keyword for different contexts.

10:03

🔧 Setting the 'this' Keyword Manually with call and apply Methods

The lecture progresses to solve the problem of the undefined 'this' keyword when calling a function outside of its original object. The instructor introduces the 'call' and 'apply' methods as tools to explicitly set 'this' to a specific object, allowing for flexibility in function calls across different contexts. Examples include booking flights for Eurowings and Lufthansa by setting 'this' appropriately using 'call', demonstrating how it enables the reuse of the book function while correctly associating bookings with their respective airlines. The 'apply' method is also mentioned, with its primary difference from 'call' being the way arguments are passed (as an array), showcasing another method of manipulating 'this'.

15:05

🛠️ Advanced Manipulation of 'this' with Modern JavaScript Techniques

In this concluding section, the focus shifts to more advanced and preferred techniques in modern JavaScript for setting 'this'. The lecturer suggests using the 'call' method with the spread operator to distribute array elements as arguments, showcasing its advantage over the 'apply' method in contemporary JavaScript development. This approach simplifies the syntax and improves readability when setting 'this'. The introduction of the 'bind' method is teased as an even more important tool for explicitly defining 'this', promising a deeper exploration in the next lecture. This part solidifies understanding of manipulating 'this' across different contexts and foreshadows the continuation of the topic.

Mindmap

Keywords

💡this keyword

The 'this' keyword in JavaScript refers to the object that is currently being used or invoked. In the video, it is central to understanding how context is determined in function calls. For instance, when a 'book' method is called on the 'Lufthansa' object, 'this' within the 'book' method refers to 'Lufthansa'. This concept is crucial to understanding the object-oriented aspects of JavaScript and how methods can interact with the data within their parent objects.

💡enhanced object literal syntax

Enhanced object literal syntax is a feature in modern JavaScript that allows more concise and readable object definitions. In the video, this syntax is used for defining methods within an object without the need to explicitly use the 'function' keyword. This makes the code cleaner and more straightforward, as seen in the 'book' method definition within the airline objects.

💡template string

Template strings in JavaScript are a way to create strings with embedded expressions, denoted by backticks (` `) and `${expression}` syntax. In the script, template strings are used for constructing dynamic messages, such as logging the flight booking details, which integrates variables like airline name and flight number directly within a string.

💡function call

A function call in JavaScript is the process of executing a function. In the video, different function calls are demonstrated, such as invoking the 'book' method. The script highlights a key aspect of function calls, specifically how the 'this' keyword behaves differently depending on whether a function is called as a method of an object or as a standalone function.

💡first-class functions

JavaScript treats functions as first-class citizens, meaning they can be assigned to variables, passed as arguments, and returned from other functions. The script demonstrates this concept by assigning the 'book' method from 'Lufthansa' to a new function, highlighting JavaScript's flexible and dynamic nature in handling functions.

💡undefined

In JavaScript, 'undefined' is a primitive value that represents the absence of a value. The script mentions that in strict mode, the 'this' keyword in a regular function call points to 'undefined'. This is a crucial concept in understanding how 'this' behaves differently in various contexts and is a common source of bugs in JavaScript code.

💡call method

The 'call' method in JavaScript is used to invoke a function with a specified 'this' value and arguments provided individually. It's central in the script's theme, illustrating how to explicitly set the 'this' context of a function, as shown when booking flights for different airlines, thereby manipulating 'this' to refer to different airline objects.

💡apply method

The 'apply' method is similar to 'call', but arguments are passed as an array. In the script, 'apply' is used as an alternative way to invoke the 'book' function with a specific 'this' context and an array of arguments. This method showcases another approach to control the execution context of functions in JavaScript.

💡spread operator

The spread operator in JavaScript, denoted by '...', allows an iterable such as an array to be expanded in places where zero or more arguments are expected. The video uses this operator to pass array elements as individual arguments to a function, illustrating a modern approach to handling function arguments flexibly.

💡bind method

The 'bind' method in JavaScript creates a new function that, when called, has its 'this' keyword set to the provided value. While not detailed in the script, it's mentioned as an important method for setting the 'this' context of a function, similar to 'call' and 'apply', but with the distinction that it returns a new function instead of immediately invoking the original function.

Highlights

Introduction to manually setting the 'this' keyword and its importance.

Creating a simple booking object for Lufthansa using enhanced object literal syntax.

Explanation of the 'this' keyword within a method, pointing to its own object.

Illustration of adding a booking to the bookings array and logging the outcome.

Introduction of Eurowings as a new airline in the Lufthansa Group, aiming for code reuse.

Storing the book method in an external function to avoid duplication and promote reuse.

Demonstration of 'this' keyword pointing to undefined in a regular function call.

Fixing the 'undefined' issue by explicitly setting the 'this' keyword using the call method.

Using the call method to manually and explicitly set the 'this' keyword for different airlines.

Addition of the Swiss Air Lines to demonstrate setting the 'this' keyword for multiple airlines.

Comparison between the call and apply methods for setting the 'this' keyword.

Introduction of the apply method and its usage with arrays for argument passing.

Highlighting the modern JavaScript practice of using the call method with the spread operator over apply.

Summary of the ability to explicitly define the 'this' keyword in any function.

Teaser for the next lecture on the bind method, which is considered more important than call and apply.

Transcripts

play00:01

In this lecture,

play00:02

we're gonna go back to the this keyword

play00:04

and learn how we can set the this keyword manually

play00:08

and also why we would want to do that.

play00:12

So let's say we are an airline again

play00:15

and in this case, Lufthansa,

play00:19

which is the biggest European airline group, by the way.

play00:23

And so let's create a very simple object

play00:26

for this airline with a very simple booking method as well.

play00:34

So we have the airline name.

play00:36

We have the code basically.

play00:42

We also want to keep an array of bookings.

play00:47

So also inside of the object,

play00:50

and then the book method.

play00:52

And remember from the previous section,

play00:54

I will now start using the way of writing methods,

play00:57

using the enhanced object literal syntax.

play01:00

And so that's simply by defining the method like this

play01:06

without having to write a function.

play01:08

So remember, before this,

play01:11

we used to do this, right?

play01:15

And if you still prefer this syntax,

play01:17

you can still do this one.

play01:19

But I do actually prefer the new syntax.

play01:22

And so I'll just start using this one now.

play01:27

So the flight number

play01:29

and also the passenger name here.

play01:33

So then let's log something to the console.

play01:37

And again, this could have been boilerplate code here

play01:40

but it's also good to practice writing this.

play01:46

So this should be a template string booked a seat on,

play01:52

so basically, we want to print like Jonas booked a seat

play01:55

on Lufthansa flight

play01:57

and then the flight number.

play01:59

And so here we are now going to get the airline name

play02:02

from the object.

play02:04

And so we already learned

play02:05

that for that, we use the this keyword, right?

play02:11

And then flight this.iataCode.

play02:18

So that's gonna be the LH

play02:20

and then the flight number itself

play02:22

that we pass into the function.

play02:24

So the flightNumber.

play02:27

So for now, this is just a nice review

play02:29

of how the this keyword works, right?

play02:34

And of course, I will now assume that you know

play02:36

how all of this works

play02:37

because otherwise, I will have to explain the same things

play02:41

over and over again.

play02:43

And so as I mentioned before,

play02:44

you should only progress once you really understand

play02:47

a certain topic.

play02:49

Anyway, let's now use the book function here.

play02:53

And I'll use the flight number 239

play02:57

and then with my own name.

play03:01

And let's right away book another Lufthansa flight

play03:06

for let's say Mike Smith on flight number 635.

play03:12

John Smith.

play03:15

And now, if we take a look at the results,

play03:17

then indeed, everything works just as expected, right?

play03:23

And so it's important to understand

play03:25

that the this keyword here points

play03:28

to the lufthansa object itself

play03:30

because that's the object

play03:31

on which the book method here was called.

play03:34

So again, that's just what I explained before, right?

play03:39

But now let's say that after some years,

play03:41

the Lufthansa Group created a new airline.

play03:45

So let's create eurowings here.

play03:52

And then a very similar object.

play03:55

So with the airline, the code.

play04:00

And also an empty bookings array.

play04:06

Okay?

play04:07

Oh, and by the way,

play04:08

we actually also want our book method here

play04:11

to add a new object to our bookings here.

play04:14

So that's super important as well.

play04:16

So I forget that.

play04:17

So let's go back here.

play04:19

So we will say again this

play04:21

and then the bookings array

play04:24

and then let's put a new object in there

play04:27

with the flight

play04:30

and so that's essentially gonna be this one.

play04:33

So the code plus the flight number.

play04:40

And then also the passenger name.

play04:42

And then let's quickly log that to the console here.

play04:48

So this.bookings is not a function

play04:52

and of course, it's not.

play04:54

We need the push method indeed.

play04:58

And so now you see that we have an array

play05:01

of our two bookings here.

play05:05

So that works perfectly.

play05:06

But now anyway, going back here to Eurowings,

play05:10

of course, we also want to be able

play05:11

to take bookings for a Eurowings flight,

play05:15

so as being this airline, right?

play05:18

Now, taking this exact same method here

play05:21

and simply copying it and pasting it here

play05:24

is a bad practice, right?

play05:26

So of course, we are not gonna do that.

play05:29

So instead, we will just take the method

play05:31

and store it in an external function.

play05:34

And then we can reuse that function

play05:36

for all of the different airlines.

play05:39

So what I mean is to create a new function called book

play05:45

and we will simply set it to lufthansa.book, all right?

play05:52

So again, this is possible

play05:54

because JavaScript has first class functions.

play05:57

And so we can simply take this function value here.

play06:01

So that's this function

play06:03

and then store it into a new variable,

play06:06

which is then gonna be also the book function, okay?

play06:10

Now, we could have written the function here also literally

play06:13

but that's just not necessary.

play06:15

We have it right here

play06:16

and so let's just leave it there

play06:18

and assign it to book right here.

play06:21

Okay, so let's try to use this book function

play06:24

to do a new booking now.

play06:27

But what do you think is gonna happen?

play06:30

So 23, and then let's say Sarah Williams

play06:37

and let's give it a save

play06:38

and now we get cannot read property airline of undefined.

play06:43

So do you know why this happened?

play06:46

Well, it's because this function here,

play06:48

the book function is now just a regular function call

play06:52

and so as we learned in one of the previous sections,

play06:55

in a regular function call,

play06:56

the this keyword points to undefined,

play06:59

at least in strict mode.

play07:02

All right?

play07:03

So once more, this book function is no longer this method.

play07:08

Okay?

play07:09

It's just not.

play07:10

It is now this separate function here.

play07:13

It's a copy of this one

play07:16

but it's not a method anymore,

play07:17

it's now a function.

play07:19

And so here it's a regular function call.

play07:21

And so therefore, the this keyword inside of it

play07:25

will now point to undefined.

play07:27

And that's why I kept telling you earlier

play07:29

that the this keyword depends on how the function

play07:32

is actually called.

play07:34

Okay, so make sure to understand these dynamics here.

play07:38

But now how do we actually fix this problem?

play07:41

So in other words, how do we tell JavaScript

play07:44

that we want to create a booking

play07:46

on the new Eurowings airline?

play07:49

Or even how do we tell it that we want

play07:51

to book on Lufthansa here?

play07:53

Well, basically, we need to tell JavaScript explicitly

play07:57

what the this keyword here should be like.

play08:00

So if we want to book a Lufthansa flight,

play08:03

the this keyword should point to Lufthansa

play08:06

but if we want to book a Eurowings flight,

play08:09

then the this keyword should point to Eurowings.

play08:12

So how do we do that?

play08:14

How do we tell JavaScript explicitly

play08:17

or manually what this this keyword should look like?

play08:21

Well, there are three function methods to do that

play08:24

and they are call, apply and bind.

play08:28

So when we first talked about the this keyword,

play08:31

I think I mentioned these methods back then

play08:33

and so now we're gonna use them,

play08:35

at least the call and apply methods.

play08:38

Okay, so let me show you how.

play08:40

So instead of just doing this,

play08:43

which doesn't work,

play08:45

let's actually comment that out.

play08:48

Does NOT work.

play08:52

So instead, we use book.call, all right?

play08:57

And remember that a function is really just an object

play09:02

and objects have methods

play09:04

and therefore, functions can have methods too

play09:07

and the call method is one of them.

play09:10

And in the call method,

play09:11

the first argument is exactly

play09:14

what we want the this keyword to point to.

play09:17

So let's say we want a Eurowings flight

play09:21

and then as usual,

play09:22

the rest of the arguments.

play09:24

So 23 and Sarah Williams.

play09:29

All right?

play09:30

And then let's log to the console also the eurowings object.

play09:34

Let's run this and then I'll explain a bit better

play09:38

what just happened.

play09:40

But indeed, we now have the bookings array

play09:43

and in there, we have the object

play09:45

with the EW23 and so EW comes from here.

play09:49

So exactly from the eurowings object

play09:52

and then also, of course, the name.

play09:54

And again, it is inside the bookings array

play09:57

of the Eurowings object.

play10:00

So let's recap what happened here.

play10:03

So this time, we did actually

play10:05

not call the book function ourselves.

play10:07

Instead, we called the call method

play10:10

and it's then this call method,

play10:12

which will call the book function

play10:14

with the this keyword set to eurowings.

play10:18

So whatever we pass has the first argument

play10:21

of the call method.

play10:22

And so this allows us to manually

play10:25

and explicitly set the this keyword

play10:27

of any function that we want to call.

play10:30

Then all the arguments after the first one

play10:33

are simply the arguments of the original function.

play10:36

And so in the case of the book function,

play10:38

of course, that's the flight number

play10:41

and the passenger name.

play10:44

And of course, now we can do the same also for Lufthansa.

play10:49

So book.call, this time with lufthansa

play10:54

and let's book someone else on flight 239.

play11:02

Let's say Mary Cooper

play11:03

and let's log again the lufthansa object

play11:08

but let's do it now here.

play11:12

And indeed, the string that we get here

play11:15

is completely correct

play11:16

and in here, so in the Lufthansa bookings array,

play11:21

we now have, of course, three bookings.

play11:25

Okay?

play11:26

And so that, of course, happened because this time,

play11:29

we set the this keyword inside

play11:30

of the function call to lufthansa.

play11:34

And so now this here is again back to pointing to Lufthansa,

play11:39

while before, right here,

play11:42

it was being pointed to Eurowings, all right?

play11:46

So even though the code of this function

play11:49

is inside of the lufthansa object,

play11:52

we made it so that the this keyword in here

play11:56

pointed to eurowings.

play11:58

So to this object, this new one right here, okay?

play12:03

So we have a way now

play12:04

of manually manipulating the this keyword

play12:07

using the call method.

play12:09

And of course, we could now keep going

play12:11

and create more airlines into the Lufthansa Group,

play12:15

like the Swiss Air Lines.

play12:23

Air Lines.

play12:25

Now, of course, these property names,

play12:27

they all need to have the exact same format

play12:31

as this original object here

play12:34

because this method is trying to read just these properties.

play12:38

So it's always iataCode

play12:40

and bookings, as you see here, and airline.

play12:44

And so of course,

play12:45

we need to use exactly these property names here as well

play12:51

but just like this,

play12:52

we can now go ahead

play12:54

and use our book function on the Swiss Air Line.

play13:00

And so this time, we will set the this keyword

play13:02

in the book.call to the swiss object.

play13:07

583 and let's book another flight for Mary Cooper here.

play13:18

And indeed, it worked again.

play13:21

So here is the booking again.

play13:26

Okay?

play13:27

There's just some weird thing here

play13:30

and so oh, actually here,

play13:33

it needs to be airline as well.

play13:35

So I was telling you you need to use the same property names

play13:39

and I wasn't even doing it myself.

play13:42

So it needs to be airline, just like it is here

play13:47

and the same here too.

play13:51

And now the string is, of course, correct here.

play13:55

Okay.

play13:56

Let me add a comment here.

play14:00

Call method because in fact,

play14:03

there is a similar method to the call method,

play14:05

which is called the apply method.

play14:09

And the apply method does basically exactly the same thing.

play14:13

The only difference is that apply

play14:15

does not receive a list of arguments

play14:18

after the this keyword,

play14:20

so it doesn't receive this list here

play14:23

but instead, it's gonna take an array

play14:25

of the arguments, okay?

play14:27

And so it will then take the elements

play14:29

from that array and pass it into the function.

play14:33

So let's say

play14:37

flightData,

play14:39

so I'm just gonna create quickly an array here

play14:41

with the flight number and the passenger name.

play14:44

So book on the same flight George Cooper

play14:50

and now we can use apply on the book function.

play14:55

So apply.

play14:57

And then just as here in the call method,

play15:00

the first argument is the this keyword.

play15:05

But now the second argument,

play15:06

it needs to be as I just said an array of data.

play15:11

So let's pass in the flightData array here.

play15:15

But then let's just take a look.

play15:18

I'll just take this one here actually.

play15:24

And so indeed, here it worked again.

play15:27

All right?

play15:29

This apply method is not that used anymore

play15:32

in modern JavaScript because now,

play15:34

we actually have a better way of doing the exact same thing.

play15:39

And do you know what I'm talking about?

play15:42

So let me show it to you.

play15:44

Book.call, so instead of using apply,

play15:49

we can still use call,

play15:51

again with swiss

play15:53

and then we can simply use the spread operator

play15:56

to take the data out of flightData

play16:00

and basically put them here.

play16:02

So this here is the same as this one.

play16:06

And so right now, with modern JavaScript,

play16:08

I prefer to just always use the call method

play16:12

and then spread out the arguments from an array like this.

play16:18

So again, this here is exactly the same as this.

play16:23

So in summary, we now have yet another tool

play16:27

in our toolbox here

play16:29

and this one is one that allows us

play16:31

to explicitly define the this keyword

play16:34

in any function that we want.

play16:36

But there is actually yet another method

play16:39

which allows us to do the same thing

play16:41

and that's the bind method.

play16:43

It's more important actually

play16:44

than the call and apply methods,

play16:46

so I'm gonna leave it for the next lecture.