- 00:00:01 welcome to this video in this video I
- 00:00:04 want to talk about something or tackle
- 00:00:06 something which I saw in a lot of
- 00:00:07 comments and also in some of my courses
- 00:00:09 that it can be hard to grasp to
- 00:00:11 understand and that is the usage of the
- 00:00:14 this keyword in JavaScript and why it
- 00:00:17 can behave strangely in some cases and
- 00:00:19 it's also that when you call a function
- 00:00:22 or a method sometimes you omit the
- 00:00:25 parentheses after the function name and
- 00:00:28 I want to talk about that queue and
- 00:00:30 explain when you call a function with
- 00:00:32 parentheses and when you use it without
- 00:00:35 these so two important things which I
- 00:00:37 see that they can lead to a lot of
- 00:00:40 confusion hopefully this video can
- 00:00:42 clarify these things
- 00:00:47 now for this video we need a tiny demo
- 00:00:50 project to get started and you can find
- 00:00:52 it attached to this video so to say
- 00:00:54 below the video you'll find a link to a
- 00:00:56 github repository with this very simple
- 00:00:59 dummy project there we got a HTML file
- 00:01:02 with a html5 skeleton in the body I got
- 00:01:06 a button saying add name
- 00:01:08 I got an unordered list with no content
- 00:01:10 but with that ID of names and I'm
- 00:01:13 importing my app.js
- 00:01:15 script which is this script of course in
- 00:01:17 there we got an error which we'll fix of
- 00:01:19 course in this video and besides that we
- 00:01:22 get this code now here I'm using
- 00:01:24 JavaScript classes in case you're not
- 00:01:26 used to using classes in JavaScript you
- 00:01:29 probably know constructor functions
- 00:01:32 constructor functions are normal
- 00:01:34 functions which you can call to create
- 00:01:36 new object and initialize them with some
- 00:01:38 properties and methods so I'm talking
- 00:01:40 about object orientated JavaScript
- 00:01:42 development and we need objects to
- 00:01:45 understand and use the this keyword that
- 00:01:47 is why I opted for the next-gen syntax
- 00:01:50 using that es6 feature of classes now
- 00:01:53 you can also take my es6 course and all
- 00:01:56 my accelerated JavaScript first fewer
- 00:01:58 and more about constructor functions and
- 00:02:00 in the year six course you'll learn
- 00:02:01 about classes here I assume you know
- 00:02:04 what classes do in the end they serve as
- 00:02:06 blueprints for us to create new objects
- 00:02:09 we do that with the new keyword this
- 00:02:11 creates a new object in this case we
- 00:02:13 store it in Gen and then don't do
- 00:02:15 anything with that object then because
- 00:02:17 name generator' which is the blueprint
- 00:02:19 or the class for that object I'm
- 00:02:21 creating has a constructor which gets
- 00:02:23 called when I call new and then the code
- 00:02:25 and here basically just gets a reference
- 00:02:27 to my button by using the button tag as
- 00:02:30 a selector and then I attach the event
- 00:02:32 listener for the click event and then
- 00:02:34 we'll need to fill this blank to tell
- 00:02:37 JavaScript which code to execute when a
- 00:02:40 click occurs then I also get a method in
- 00:02:43 this class here a method is just a
- 00:02:46 function in a class you could say it's
- 00:02:48 called add name and in there I create a
- 00:02:51 new instance off the name field class so
- 00:02:54 I create a new object again I don't do
- 00:02:56 anything with that object but one thing
- 00:02:59 I do is I create
- 00:03:00 here we get a constructor and in that
- 00:03:03 constructor I simply create a new list
- 00:03:04 item I then whoops set some text to that
- 00:03:09 list item the text is the argument I'm
- 00:03:11 getting here essentially the name which
- 00:03:14 I want to output and the name is passed
- 00:03:16 here right now it's always max I'll
- 00:03:18 change this and then I get a reference
- 00:03:21 to my unordered list with that ID
- 00:03:24 selector using that names ID here and I
- 00:03:27 add that name now let's make this work
- 00:03:32 by first of all removing these free
- 00:03:34 question marks and here I obviously want
- 00:03:37 to call add name I want to execute that
- 00:03:39 add name method now for this we already
- 00:03:42 need to use the two things this video is
- 00:03:44 about this and we also need to use or
- 00:03:49 call a function in a special way you
- 00:03:51 could say because here I want to execute
- 00:03:54 add name and you could think we just
- 00:03:56 specify add name like this this would be
- 00:03:59 wrong due to two reasons first of all if
- 00:04:03 we specify like this JavaScript would
- 00:04:05 look for a variable called add name or a
- 00:04:08 function called add name in the scope of
- 00:04:11 this constructor and if it doesn't find
- 00:04:14 it there in the global scope in the
- 00:04:16 overall file you could say in the on the
- 00:04:18 whole window to which this script is
- 00:04:21 attached now we got no add name variable
- 00:04:24 or function in the constructor and we
- 00:04:26 also got anon in the overall file or
- 00:04:28 anywhere else in this app so this will
- 00:04:30 not work and I can prove this to you if
- 00:04:32 we save that and I open my developer
- 00:04:34 tools here and I reload this page we
- 00:04:37 already see add name is not defined
- 00:04:40 because it doesn't find it because a
- 00:04:43 method what we have here is attached to
- 00:04:46 this object so to this class and
- 00:04:48 therefore to the object we create based
- 00:04:50 on the class if we want to tell
- 00:04:52 JavaScript that I want to access
- 00:04:55 function that is attached to the class
- 00:04:57 so to say we need that special this
- 00:05:00 keyword this essentially refers Judah
- 00:05:03 object the code is in so here this line
- 00:05:07 of code is in this object in the name
- 00:05:09 generator so if you want to refer to
- 00:05:11 anything else that is attached to the
- 00:05:13 name generator like
- 00:05:14 at name we need to prepend this and then
- 00:05:17 dot because this essentially gives us
- 00:05:20 access to this object and that we can
- 00:05:22 call methods or access properties on
- 00:05:24 that object with the dot notation so ad
- 00:05:27 name now it calls dysfunction on this
- 00:05:30 object this is how we can use this we're
- 00:05:33 still not there though if I save this
- 00:05:36 and I reload hmm I get max here without
- 00:05:40 me touching that button on the other end
- 00:05:42 if I do click the button nothing happens
- 00:05:44 and we also get no error which makes
- 00:05:47 that super hard to debug of course now
- 00:05:50 the problem we got here is this function
- 00:05:53 gets executed immediately and why is
- 00:05:57 that because I have parentheses here
- 00:06:00 what happens is JavaScript reads that
- 00:06:03 code from top to bottom and it does read
- 00:06:06 and parse that code when the script gets
- 00:06:08 first executed which happens when the
- 00:06:11 browser parses this HTML file and
- 00:06:13 reaches the script import it then
- 00:06:15 immediately goes to the script file and
- 00:06:17 parses dead this is important because
- 00:06:19 this allows us to start our scripts when
- 00:06:22 the page is loaded and load everything
- 00:06:23 into memory and let the browser do its
- 00:06:26 job however as it goes through that file
- 00:06:30 it all defines this line and here what I
- 00:06:34 do is I simply execute a function this
- 00:06:37 is how I execute a function right I use
- 00:06:39 the function name and the fact that it's
- 00:06:41 a method here because it's attached to a
- 00:06:43 class it doesn't change that I use the
- 00:06:45 function or method name I add
- 00:06:47 parentheses I could pass any arguments
- 00:06:50 if that function would accept any and
- 00:06:52 we're done this executes a function the
- 00:06:55 problem is here I don't want to execute
- 00:06:58 it immediately when I wanted to in
- 00:06:59 status I just want to tell JavaScript
- 00:07:02 that it should register this event
- 00:07:05 listener and eventually execute this
- 00:07:08 function when that click occurs so not
- 00:07:11 immediately only when that click occurs
- 00:07:13 and to do that I remove these
- 00:07:16 parentheses so the two parentheses I had
- 00:07:20 after add name if I now save this and I
- 00:07:23 reload we don't see Mac's right from the
- 00:07:25 start but if I click the button
- 00:07:28 now I'm adding my list items now why is
- 00:07:31 that because my right now what I'm doing
- 00:07:34 is I'm just passing a reference to my
- 00:07:37 function so like an address you could
- 00:07:39 say to that event listener so I'm
- 00:07:42 basically just telling JavaScript hey
- 00:07:44 here is the address of the function or
- 00:07:47 method you should execute when they
- 00:07:50 click occurs so that you know where to
- 00:07:52 find it when you need to call it because
- 00:07:54 we don't call that function on our own
- 00:07:57 JavaScript does that so to say the
- 00:07:59 browser does that it does that when the
- 00:08:02 click occurs that is exactly what we're
- 00:08:04 setting up here so we just passed the
- 00:08:06 address to the function with parentheses
- 00:08:09 like this we would execute it
- 00:08:11 immediately we don't want to do that
- 00:08:13 therefore without parentheses we just
- 00:08:17 passed the reference the address of the
- 00:08:19 function to the code which should be
- 00:08:21 aware of it and which should execute it
- 00:08:23 when the time is used so when we click
- 00:08:25 this is the important concept here that
- 00:08:28 we're just passing the reference that
- 00:08:30 we're just passing the address to the
- 00:08:32 function and this is perfectly valid and
- 00:08:34 normal JavaScript code this is no
- 00:08:36 workaround or trick or a hack or
- 00:08:37 anything like that this is a normal way
- 00:08:39 of doing that now this is working
- 00:08:43 now let's tweak that code a little bit
- 00:08:45 because this can actually behave
- 00:08:47 strangely right now it doesn't but it
- 00:08:49 can let's say that in this class here we
- 00:08:53 want to manage a list of names and cycle
- 00:08:57 through these names so we could have
- 00:08:59 something like names and that is an
- 00:09:02 array let's say and in there i got max I
- 00:09:06 got my colleague menu and I got an ax so
- 00:09:09 I got these three names and my idea is
- 00:09:11 that for every click I want to output a
- 00:09:13 different name now to do that I need to
- 00:09:16 get access to my name's an add name
- 00:09:18 because that is ultimately where I pass
- 00:09:20 the name – name field now obviously one
- 00:09:24 easy workaround would be to simply move
- 00:09:25 that constant down there but let's
- 00:09:28 pretend we need that in other places of
- 00:09:30 this name generator class – in that case
- 00:09:34 I want to manage it globally simply like
- 00:09:37 that method is available from anywhere
- 00:09:39 in this class – with this
- 00:09:41 I want to make my name's available from
- 00:09:44 anywhere in this class and therefore I
- 00:09:46 can create a property of field named
- 00:09:50 names and I do this by adding this dot
- 00:09:52 at the beginning and what this does is
- 00:09:54 it's now not a constant or variable
- 00:09:57 anymore instead you could say it's a
- 00:09:59 variable attached to this class a so
- 00:10:02 called property or field so now this
- 00:10:05 names can be used from anywhere inside
- 00:10:08 this class and by the way although only
- 00:10:11 instantiated object there we can call
- 00:10:14 add name because it's part of the class
- 00:10:17 and we can access names because it's
- 00:10:19 part of that class due to that this
- 00:10:21 keyword so this really combines or
- 00:10:25 attaches things to the entire class and
- 00:10:27 therefore to the entire object which
- 00:10:29 gets created and what this allows me to
- 00:10:31 do is I can now access this names down
- 00:10:35 there and now here an add name I'm
- 00:10:38 referring to my array of names which I'm
- 00:10:40 setting up in a constructor and this is
- 00:10:42 how we initialize a property or field in
- 00:10:45 a constructor and how we then use it
- 00:10:46 somewhere else
- 00:10:47 however I of course don't just want to
- 00:10:50 use the entire array down there I want
- 00:10:52 to cycle through my names so add another
- 00:10:54 property and I'll name it current name
- 00:10:56 the names of these properties are of
- 00:10:59 course up to you and I'll set this equal
- 00:11:01 to a number zero because index starts at
- 00:11:05 index zero and I want to start with name
- 00:11:07 first because now what I can do is I can
- 00:11:09 access the first element with this
- 00:11:11 current name so current name is null is
- 00:11:14 zero initially so I access the first
- 00:11:17 element in my array here down there
- 00:11:19 first array element is Max and I passed
- 00:11:22 that name field now of course I want to
- 00:11:24 change current name with every click so
- 00:11:27 after creating the name field I can set
- 00:11:30 current name to current name plus one
- 00:11:33 with that plus plus shortcut we only got
- 00:11:36 three elements in the array so what I
- 00:11:38 want to check here is if this current
- 00:11:42 name is greater than this names length
- 00:11:47 then I need to reset it because then we
- 00:11:51 exceeded the array now actually this is
- 00:11:54 not
- 00:11:55 correct check because the length of this
- 00:11:58 array will be free and I actually
- 00:12:00 already exceeded or exhausted the entire
- 00:12:03 array if current name is two because the
- 00:12:06 index starts at zero if current name is
- 00:12:08 two will have extracted the name Ana so
- 00:12:11 therefore I actually want to convert
- 00:12:13 this to greater than or equal to length
- 00:12:15 length is free and if we incremented
- 00:12:18 current name to free we know we don't
- 00:12:20 have a element for that
- 00:12:21 so let's reset it now let's see if that
- 00:12:25 works if I reload and I click add name
- 00:12:28 hmm I get an error and the error is that
- 00:12:31 I cannot read the property and the find
- 00:12:33 of undefined and it occurs in line 19
- 00:12:37 now line 19 is this line where I try to
- 00:12:40 use names and current name and do you
- 00:12:43 have any idea what's the issue here now
- 00:12:47 in theory that code should work but now
- 00:12:49 we got a special thing of the this
- 00:12:52 keyword this does not always refer to
- 00:12:57 the surrounding object so to say to the
- 00:13:00 class it's generally what it refers to
- 00:13:04 you could say in most cases but actually
- 00:13:07 this is to find a bit differently in
- 00:13:08 JavaScript this refers to whoever called
- 00:13:14 the function in which you use this so an
- 00:13:18 add name we're using this and now who
- 00:13:21 did call or what's responsible for
- 00:13:23 executing this function this is not this
- 00:13:26 class indirectly it is but not directly
- 00:13:29 directly the responsible thing is our
- 00:13:33 button event here and we can show this
- 00:13:36 by console logging this let's look into
- 00:13:39 this let's see what this is when we
- 00:13:41 execute add name if I click here we see
- 00:13:44 it's the button so the button is this
- 00:13:48 here and that is the case because this
- 00:13:52 event listener and therefore the button
- 00:13:55 is executing our function when we click
- 00:13:58 we pass the address to the function to
- 00:14:01 the button or to the event listener and
- 00:14:03 we say execute the function for us when
- 00:14:06 a click occurs and then this simple
- 00:14:09 first to the button this is how it works
- 00:14:10 in JavaScript it's not always the object
- 00:14:13 in which you write your code it's the
- 00:14:15 thing which calls your code which
- 00:14:16 executes your code you could say and
- 00:14:18 that method gets executed by the button
- 00:14:20 when a click occurs just to prove this
- 00:14:24 if I console.log this in a constructor
- 00:14:27 here then we see there it's referring to
- 00:14:31 the name generator object to the class
- 00:14:33 to the constructor function and that is
- 00:14:36 the case because this code here is not
- 00:14:39 executed by the button or anything like
- 00:14:41 that it's simply parsed by JavaScript
- 00:14:43 from top to bottom and therefore this
- 00:14:45 then refers to the class to the object
- 00:14:47 that surrounds it this can be hard to
- 00:14:50 understand and the end it is just
- 00:14:52 something you can memorize this refers
- 00:14:54 to what's executing the code and here
- 00:14:57 the so here in the constructor the what
- 00:14:59 is executing the code is simply just
- 00:15:02 well here this line in the end this is
- 00:15:04 calling the constructor and therefore
- 00:15:06 here we call the code and this in here
- 00:15:10 refers to the constructor now for add
- 00:15:14 name the button calls add name and this
- 00:15:16 then refers to the button and not to
- 00:15:19 this class anymore on the other hand if
- 00:15:21 we would call add name here directly and
- 00:15:24 not wait for a button click so we
- 00:15:26 executed the constructor here and I
- 00:15:29 reload then you see it works and this
- 00:15:31 actually also refers to the name
- 00:15:33 generator the reason for this is that we
- 00:15:34 again execute the code in the scope of
- 00:15:37 this constructor therefore the
- 00:15:39 constructor and therefore the class is
- 00:15:41 executing this line so this refers to
- 00:15:43 who executed it and that is our
- 00:15:46 constructor and therefore the class this
- 00:15:48 is how this works now how can we change
- 00:15:51 that behavior one way of changing it is
- 00:15:55 to use a special method we can call and
- 00:15:58 that is a method we can call on any
- 00:16:00 function it's the bind function bind
- 00:16:04 actually allows us to tell JavaScript
- 00:16:06 what this should be referring to in the
- 00:16:10 function that will eventually get
- 00:16:12 executed so born still does not
- 00:16:14 immediately execute the function we keep
- 00:16:17 that behavior of just passing the
- 00:16:18 address but we configured a function for
- 00:16:21 the time when it
- 00:16:22 we'll get executed so to say and we do
- 00:16:24 so with the first argument by telling it
- 00:16:26 what should this refer to in the
- 00:16:30 function when it gets executed in the
- 00:16:32 future no matter who executes it
- 00:16:34 and if I find this year I'm telling
- 00:16:37 JavaScript that this incite this method
- 00:16:40 should refer to the same thing this
- 00:16:43 refers to in a constructor and as we
- 00:16:46 just saw with console.log in the
- 00:16:48 constructor this refers to the class and
- 00:16:51 not to the button so here I'm telling
- 00:16:54 JavaScript no matter who executes this
- 00:16:57 add name this inside of that name should
- 00:17:01 always refer to this in the constructor
- 00:17:05 to whatever this is and this and the
- 00:17:07 constructor simply is our class because
- 00:17:09 we're calling our constructor down there
- 00:17:12 this is one way of ensuring that this
- 00:17:15 code down there will work if I now save
- 00:17:18 this and I reload you see I can cycle
- 00:17:22 through my names and output them there
- 00:17:24 and now this works as intended and I
- 00:17:26 know that this can be hard to wrap your
- 00:17:28 head around it's a special thing and in
- 00:17:30 the end if you encounter any issues with
- 00:17:33 you using this and suddenly it doesn't
- 00:17:35 work check if your may be calling your
- 00:17:39 function indirectly through some event
- 00:17:41 listener or anything like that and
- 00:17:43 therefore this and a function that gets
- 00:17:45 executed might not be referring to your
- 00:17:47 object anymore now when our way of
- 00:17:51 solving this by the way is that you pass
- 00:17:53 an anonymous function here and that
- 00:17:56 anonymous function has to be an arrow
- 00:17:57 function let's first of all use a normal
- 00:17:59 anonymous function so I have I define a
- 00:18:02 function in place this function here is
- 00:18:05 not executed immediately it's just a
- 00:18:08 find and it will still be executed by
- 00:18:10 the click listener and in there I can of
- 00:18:12 course call add name this add name like
- 00:18:16 this now this line again will not be
- 00:18:18 executed immediately
- 00:18:19 because this is executed immediately but
- 00:18:22 the code in this function is not instead
- 00:18:24 this code being executed immediately
- 00:18:26 just registers the function in memory
- 00:18:28 and passes it to the event listener so
- 00:18:31 if I save this you see nothing gets
- 00:18:33 rendered so this add name is not
- 00:18:36 executed immediately but clicking on add
- 00:18:38 name gives us another issue that add
- 00:18:42 name this add name is not a function and
- 00:18:44 the reason for this is that again this
- 00:18:46 in here in this anonymous function will
- 00:18:49 not refer to or class but to the button
- 00:18:53 because essentially we just did the same
- 00:18:55 with that before before using bind now
- 00:18:58 when using an anonymous arrow function
- 00:19:01 which is all the next generation
- 00:19:03 JavaScript syntax introduced with es6
- 00:19:05 then this changes now if I save this in
- 00:19:08 a reload it works
- 00:19:11 and the reason for that is that arrow
- 00:19:13 functions specifically solve that
- 00:19:16 problem of this behaving differently
- 00:19:19 because often you don't want it to
- 00:19:21 behave differently and therefore arrow
- 00:19:23 functions were introduced to basically
- 00:19:25 keep the context of this or the
- 00:19:28 reference of this so if you use an arrow
- 00:19:31 function here this will refer to the
- 00:19:34 exact same thing it would refer to if it
- 00:19:36 were used outside of that arrow function
- 00:19:38 this is the idea behind them and
- 00:19:40 therefore now this and here refers to
- 00:19:42 the constructor now we call ad name on
- 00:19:45 this so on our constructor and therefore
- 00:19:48 in the function in ad name this refers
- 00:19:51 to called it who called it well
- 00:19:53 our constructor so this inside here
- 00:19:56 still refers to our constructor to our
- 00:19:58 class a lot of mind yoga here I guess
- 00:20:02 but really something which helps you a
- 00:20:04 lot once you wrap your head around and
- 00:20:06 really something I also encourage you to
- 00:20:08 just play around with you got the code
- 00:20:10 you got the finished code to below the
- 00:20:12 video and I hope that this was helpful
- 00:20:13 see you in future videos hopefully bye