Coding

Making Sense of the Tricky Parts of JavaScript

  • 00:00:00 javascript can be confusing right that
  • 00:00:02 this keyword prototypes callback
  • 00:00:05 functions scope and hoisting and a
  • 00:00:07 couple of other things especially if
  • 00:00:10 you're new to JavaScript but even as a
  • 00:00:12 bit of a more experienced developer
  • 00:00:14 these things can be tricky now in this
  • 00:00:17 video as well as in an article below the
  • 00:00:20 video and a course which can optionally
  • 00:00:22 take I compiled these different strange
  • 00:00:26 aspects to hopefully make them a bit
  • 00:00:28 less strange
  • 00:00:33 scope and hoisting are key concepts of
  • 00:00:36 JavaScript and this snippet shows us
  • 00:00:39 both in action now what's scope the
  • 00:00:42 scope is all about the visibility of
  • 00:00:44 variables so where in your code you can
  • 00:00:47 use which variable for example that we
  • 00:00:50 can access the result variable here
  • 00:00:52 inside of this function but also here
  • 00:00:54 outside of the function is possible
  • 00:00:57 because we declare and define it here in
  • 00:00:59 line 1 and therefore this function uses
  • 00:01:02 the so-called global scope actually
  • 00:01:05 since it's created with let it
  • 00:01:07 technically uses block scope but this
  • 00:01:09 all sets in one big block of code and in
  • 00:01:13 JavaScript scopes work such that the
  • 00:01:16 variables defined in a scope can be used
  • 00:01:19 anywhere in that scope but also in any
  • 00:01:22 child in any nested scope now it turns
  • 00:01:26 out functions create their own scope if
  • 00:01:28 you create variables in there with the
  • 00:01:30 VAR keyword those variables have
  • 00:01:32 function scope or if you create
  • 00:01:35 variables with let or a constant there
  • 00:01:37 those variables or constants have block
  • 00:01:40 scope because functions just like if
  • 00:01:43 statements and for loops create new
  • 00:01:45 blocks of code so a variable defined in
  • 00:01:49 a higher-level scope can be used in a
  • 00:01:52 nested scope so global scope can be used
  • 00:01:55 inside of this function or block scope
  • 00:01:57 it would not work the other way around
  • 00:01:59 if I have a new result here where I use
  • 00:02:02 basically the other result I could not
  • 00:02:05 use new result anywhere here no matter
  • 00:02:08 where I try to use it this would not
  • 00:02:10 work because this is now a constant
  • 00:02:12 created in this block of code and
  • 00:02:15 therefore it's only available in there
  • 00:02:17 or in any other nested scope that's what
  • 00:02:21 scope is about in the end and knowing it
  • 00:02:24 it's very important because it explains
  • 00:02:26 why you can access certain variables in
  • 00:02:29 some parts of your code and why you
  • 00:02:31 can't in a verse now another important
  • 00:02:34 concept in JavaScript which also can be
  • 00:02:36 tricky to wrap your head around is the
  • 00:02:39 concept of hoisting hoisting is in the
  • 00:02:42 end just a core mechanism built into
  • 00:02:45 JavaScript or
  • 00:02:46 into JavaScript engines that run your
  • 00:02:48 code dead in the end and ables
  • 00:02:51 javascript to be aware of certain
  • 00:02:53 variables and functions before the code
  • 00:02:56 execution reaches the function or
  • 00:02:59 variable declaration okay that's a very
  • 00:03:02 technical turn what does it mean well we
  • 00:03:04 see it here we're calling add one in
  • 00:03:07 line three but keep in mind that we
  • 00:03:10 actually only declare and define this
  • 00:03:12 function here in lines six to nine now
  • 00:03:16 because of the hoisting mechanism
  • 00:03:18 JavaScript essentially goes over your
  • 00:03:21 entire file before it starts executing
  • 00:03:23 it and you could say it memorizes all
  • 00:03:27 those function declarations so functions
  • 00:03:30 written like this and that's why you're
  • 00:03:33 then able to call such a function when
  • 00:03:35 the code execution begins before the
  • 00:03:38 code execution reached those lines down
  • 00:03:40 they're important for hoisting is that
  • 00:03:43 it really only works in that way if you
  • 00:03:46 have a function declaration so if you
  • 00:03:48 use this function declaration syntax if
  • 00:03:51 instead we would have created a add one
  • 00:03:54 constant and stored an anonymous
  • 00:03:56 function in there and hence we would
  • 00:03:58 have used this function expression
  • 00:04:00 syntax the add one variable would kind
  • 00:04:04 of be hoisted but you wouldn't be able
  • 00:04:06 to call it so hoisting is really most
  • 00:04:08 important to be aware of or to utilize
  • 00:04:11 if you're using this syntax because this
  • 00:04:14 then allows you to move functions to the
  • 00:04:16 end of your file which can help you
  • 00:04:18 organize your code
  • 00:04:22 primitive values and reference values
  • 00:04:25 that's a topic that's definitely
  • 00:04:27 confusing to a lot of developers numbers
  • 00:04:30 in JavaScript as well as strings
  • 00:04:33 bullying's undefined symbol and big int
  • 00:04:36 for big integer are so-called primitive
  • 00:04:39 values any object in JavaScript is a
  • 00:04:43 reference value and for that it's
  • 00:04:45 important to keep in mind that arrays
  • 00:04:47 and functions are also objects in
  • 00:04:50 JavaScript now that's a nice
  • 00:04:52 differentiation but what's the idea
  • 00:04:54 behind it what does it mean primitive
  • 00:04:56 values so numbers strings boolean's and
  • 00:04:59 so on are immutable and shared by copy
  • 00:05:03 reference values are mutable and shared
  • 00:05:06 by well reference but again what does
  • 00:05:09 this mean here's an example we have a
  • 00:05:11 number one analog number plus two and
  • 00:05:14 then I also change number here and store
  • 00:05:17 a new number in the number variable now
  • 00:05:20 this is straightforward code but it is
  • 00:05:23 important to realize and understand as
  • 00:05:25 developer that behind the scenes the
  • 00:05:28 value 1 here is actually never changed
  • 00:05:31 when we add 2 to it we're not changing
  • 00:05:34 the 1 the one always stays a 1 we of
  • 00:05:38 course do something else we derive a
  • 00:05:40 brand new value of 3 here and we output
  • 00:05:44 this year so neither the value stored in
  • 00:05:46 the variable has changed nor the value
  • 00:05:48 itself behind the scenes in memory it's
  • 00:05:51 always a 1 we just derive a new value
  • 00:05:53 here and this is achieved by copying it
  • 00:05:56 by value so what this means is that when
  • 00:05:59 we have a calculation where we use a
  • 00:06:02 value that 1 is simply copied here and
  • 00:06:05 we derive a brand-new value the same
  • 00:06:08 here and when we then store it is back
  • 00:06:10 in number we're not changing the old
  • 00:06:12 value the 1 still is a 1 we just don't
  • 00:06:15 need that one anymore we copied it here
  • 00:06:19 so that we can derive a brand new value
  • 00:06:21 the 4 but then the original 1 is simply
  • 00:06:24 dumped we don't need it anymore we got a
  • 00:06:26 brand new value of 4 and that 4 is
  • 00:06:29 stored here in number now that's just
  • 00:06:32 some theory which is nice to know but
  • 00:06:34 which doesn't really change how you
  • 00:06:36 your code you probably didn't expect
  • 00:06:39 anything else than what I explained here
  • 00:06:41 from this code anyways right well it
  • 00:06:44 gets more interesting when we talk about
  • 00:06:45 reference values because that's the
  • 00:06:48 tricky part as I said any object in
  • 00:06:51 JavaScript is a reference value and that
  • 00:06:53 includes arrays and functions now here
  • 00:06:56 we have a straightforward simple object
  • 00:06:58 an object with an age property which has
  • 00:07:00 a value of 31 now the 31 of course is a
  • 00:07:03 primitive value it's a number but the
  • 00:07:05 overall object is a reference value now
  • 00:07:08 I create a new constant me and I saved
  • 00:07:12 as object which is stored in person in
  • 00:07:14 me because I point at person here and
  • 00:07:16 then I changed the person age set it to
  • 00:07:19 32 analog me age so I changed the age of
  • 00:07:23 person not of me but then I log me age
  • 00:07:26 and if you would lock this you would see
  • 00:07:28 that indeed you get 32 as output not 31
  • 00:07:32 even though we never changed me dot age
  • 00:07:35 and the reason for that is that
  • 00:07:37 reference values in JavaScript are
  • 00:07:39 stored such that we have one object
  • 00:07:42 stored in memory and what's stored in
  • 00:07:44 the constant here or in the variable
  • 00:07:46 doesn't matter is a pointer at this
  • 00:07:49 object in memory so the address of that
  • 00:07:52 object in memory you could say the
  • 00:07:54 reference to it that's stored in a
  • 00:07:57 constant and when we create a new
  • 00:07:58 constant here we just copied that
  • 00:08:01 pointer and store it in a new constant
  • 00:08:03 as well but if we then use that pointer
  • 00:08:05 to manipulate the value we work on one
  • 00:08:08 and the same value in memory because
  • 00:08:10 that value in memory was never copied or
  • 00:08:13 cloned or anything like that it's one of
  • 00:08:15 the same object with one pointer and
  • 00:08:18 just that pointer was copied and that's
  • 00:08:21 why we manipulate the object stored in
  • 00:08:24 me when we assign a new age to the
  • 00:08:27 person object because it's not two
  • 00:08:30 different objects it's one object in
  • 00:08:32 memory and that's also why we can
  • 00:08:34 manipulate a Const this is a con so we
  • 00:08:37 can't change the value stored in there
  • 00:08:39 right why can we then assign a new age
  • 00:08:41 well because we're not assigning a new
  • 00:08:43 value to person with that we're changing
  • 00:08:45 the value the pointer point set but
  • 00:08:48 what's stored in this con
  • 00:08:50 is not that object but the pointer and
  • 00:08:53 the pointer doesn't change we wouldn't
  • 00:08:56 be allowed to assign a new value to
  • 00:08:58 person let's say a new object this would
  • 00:09:02 throw an error because here we really
  • 00:09:04 would create a new object a new pointer
  • 00:09:06 and try to store it in person but what
  • 00:09:09 we do here is perfectly fine because
  • 00:09:10 we're just changing an existing object
  • 00:09:12 in memory now there are techniques how
  • 00:09:15 you can copy an object so how you can
  • 00:09:17 not just copy the pointer but the full
  • 00:09:20 object and I do dive into that in the
  • 00:09:22 resources below the video but for now
  • 00:09:24 that's what you need to know about
  • 00:09:25 primitives and reference values
  • 00:09:30 closures can be the cause of a lot of
  • 00:09:32 trouble if you don't know how they
  • 00:09:34 behave and what they are now in general
  • 00:09:36 every function in JavaScript is or to be
  • 00:09:39 precise for ins a closure now that
  • 00:09:42 doesn't help you too much right now
  • 00:09:44 what's a closure a function JavaScript
  • 00:09:46 as we have it here simply closes over
  • 00:09:49 its environment when it's created and
  • 00:09:52 that means one simple thing it memorizes
  • 00:09:55 the variables it has access to when the
  • 00:09:58 code that creates it executes it and the
  • 00:10:01 consequence simply is that if a function
  • 00:10:03 is called at a later point of time like
  • 00:10:06 this anonymous function here which we
  • 00:10:08 call only after one and a half second it
  • 00:10:10 still has access to this my name
  • 00:10:12 variable here even though it's running
  • 00:10:14 in the future so when the average code
  • 00:10:16 execution already finished it still has
  • 00:10:19 access to my name because the
  • 00:10:21 environment of this function when it was
  • 00:10:23 created contained to my name variable
  • 00:10:25 because of that scope concept we have
  • 00:10:27 access to the global my name variable
  • 00:10:29 here in this anonymous function but
  • 00:10:32 closures can still be tricky we have
  • 00:10:34 access to my name so what would you
  • 00:10:36 expect as an output here if I load this
  • 00:10:39 page keep in mind that this runs after
  • 00:10:41 one and a half second do you expect max
  • 00:10:44 here which is the value we have when we
  • 00:10:46 call that function that sets the timer
  • 00:10:48 or do you expect Maximilian which I
  • 00:10:50 change after calling this function that
  • 00:10:52 sets the timer
  • 00:10:53 well it's Maximilian and this might or
  • 00:10:57 might not be what you expected now I
  • 00:10:59 think it would be reasonable if you
  • 00:11:02 expected max as an output instead of
  • 00:11:04 Maximilian after all when we set the
  • 00:11:07 timer when we called greet me with delay
  • 00:11:09 the value was max so if the function
  • 00:11:13 this anonymous function in this case
  • 00:11:15 closes over its environment and in this
  • 00:11:19 environment my name is Max at the point
  • 00:11:22 of time we create this function why do
  • 00:11:24 we then output Maximilian when the
  • 00:11:26 function actually runs because and
  • 00:11:29 that's important functions closures in
  • 00:11:32 JavaScript closed over the variable
  • 00:11:35 names you could say they memorize the
  • 00:11:38 variable names not the variable values
  • 00:11:41 the value is only look
  • 00:11:43 up when the function actually runs so
  • 00:11:46 the value for my name is only looked up
  • 00:11:49 when this anonymous function is executed
  • 00:11:51 which happens when a timer completed and
  • 00:11:53 at that point of time the value is
  • 00:11:56 Maximilian because we immediately
  • 00:11:58 changed his after setting the timer and
  • 00:12:00 that's the essence of closures in the
  • 00:12:03 end
  • 00:12:06 recursion is a concept that's not
  • 00:12:08 exclusive to JavaScript actually a lot
  • 00:12:10 of concepts covered here are not
  • 00:12:12 necessarily exclusive to JavaScript but
  • 00:12:14 recursion can simply be tricky because
  • 00:12:17 it's it can be difficult to wrap your
  • 00:12:19 head around it and here's a simple
  • 00:12:21 example for it
  • 00:12:22 recursion is basically just a function
  • 00:12:24 calling itself like we're doing it here
  • 00:12:27 we're calling factorial from inside
  • 00:12:30 factorial and yes this is something
  • 00:12:32 you're allowed to do in JavaScript now
  • 00:12:35 why might you want to do it simply
  • 00:12:37 because recursion sometimes allows you
  • 00:12:39 to write less code then you would have
  • 00:12:41 to write with a loop or in some cases
  • 00:12:44 like if you're traversing some tree
  • 00:12:46 structure recursion might even be your
  • 00:12:49 only strategy of handling a certain
  • 00:12:51 situation like in such a tree structure
  • 00:12:54 traversal situation where you don't know
  • 00:12:57 in advance how many iterations you might
  • 00:12:59 need because you have a nested object
  • 00:13:01 and you need to go through all levels of
  • 00:13:03 nesting something like that I cover that
  • 00:13:05 in my course but even in this simple
  • 00:13:07 case this can be shorter than the loop
  • 00:13:10 you would have to write otherwise now a
  • 00:13:12 good recursive function in the end
  • 00:13:15 always has at least two components a
  • 00:13:17 base case which is basically your non
  • 00:13:20 recursive exit condition where you
  • 00:13:23 return a value where you don't call
  • 00:13:25 yourself and recursive step which is
  • 00:13:27 essentially you calling yourself if you
  • 00:13:30 only have recursive steps so if you have
  • 00:13:33 no branch in the function where you
  • 00:13:34 don't call yourself you of course create
  • 00:13:37 an infinite loop and you don't want that
  • 00:13:39 and therefore you need some condition in
  • 00:13:41 every recursive function in the end that
  • 00:13:44 cancels the recursion and gets you out
  • 00:13:46 of it now if I lock this here we
  • 00:13:49 therefore a see the result six and if
  • 00:13:51 you want to look behind the scenes of
  • 00:13:53 recursion you can do this as well with
  • 00:13:54 the developer tools for example by
  • 00:13:57 simply adding a breakpoint here in your
  • 00:13:59 recursive function if I now reload it
  • 00:14:02 stops here and what you see here in the
  • 00:14:04 developer tools is to call stack the
  • 00:14:07 call stack is a mechanism that's part of
  • 00:14:09 the JavaScript engine in the end which
  • 00:14:11 managers running function executions
  • 00:14:13 javascript is only capable of executing
  • 00:14:15 one function at a time but it can you
  • 00:14:18 could say pause of
  • 00:14:19 function execution to wait for another
  • 00:14:21 function to finish and you can see this
  • 00:14:23 here if I continue here and I step into
  • 00:14:26 the next function execution you now see
  • 00:14:29 on the call stack we have Q factorial
  • 00:14:31 function executions going on and the one
  • 00:14:33 with the blue arrow is the one we're
  • 00:14:35 currently in and that's recursion in
  • 00:14:37 action we got more and more ongoing
  • 00:14:40 factorial function executions but only
  • 00:14:42 the top one is the one that's currently
  • 00:14:44 executing and at some point once we made
  • 00:14:48 it deep enough into all of that we make
  • 00:14:51 it out of the recursion and go through
  • 00:14:53 that call stack from top to bottom to
  • 00:14:56 basically return the value of every
  • 00:14:58 nested function execution to the next
  • 00:15:01 one in line in the call stack until
  • 00:15:03 we're back to the main function
  • 00:15:04 execution which then ultimately is able
  • 00:15:07 to complete and return us the value were
  • 00:15:09 interested in
  • 00:15:10 that's how recursion works under the
  • 00:15:12 hood and that's how you can debug it and
  • 00:15:14 how you can hopefully avoid a lot of
  • 00:15:16 headaches related to that
  • 00:15:20 callbacks and related to that direct
  • 00:15:23 versus indirect function execution can
  • 00:15:25 also be confusing to newcomers here is a
  • 00:15:28 classic scenario of regular direct
  • 00:15:31 function execution we have a function we
  • 00:15:34 then call it and you call a function
  • 00:15:37 when you basically add parentheses after
  • 00:15:39 the function name after having the
  • 00:15:41 function to find of course this then
  • 00:15:44 executes this function right away and
  • 00:15:45 runs whichever code is in it now here's
  • 00:15:48 an example for indirect function
  • 00:15:50 execution where we utilize a callback we
  • 00:15:53 add a listener to a button here and this
  • 00:15:56 add event listener method does not only
  • 00:15:58 take the kind of event you want to
  • 00:16:00 listen to but also the function that
  • 00:16:02 should be executed when the click occurs
  • 00:16:04 and I often get asked why we don't have
  • 00:16:07 parentheses here the reason is simple if
  • 00:16:10 we would have parentheses here after add
  • 00:16:13 user in line 9 we would immediately
  • 00:16:15 execute add user when Javas good reaches
  • 00:16:18 this line of code now it reaches this
  • 00:16:20 line of code not when a click occurs
  • 00:16:22 though but when it simply adds to click
  • 00:16:24 listener and that's of course not when
  • 00:16:26 you want to call this function this
  • 00:16:28 should fire when the click occurs
  • 00:16:30 instead so adding parentheses here is
  • 00:16:33 definitely wrong because that would
  • 00:16:35 always lead this function to be called
  • 00:16:37 when the listener is added not when they
  • 00:16:39 click occurs if you remove the
  • 00:16:42 parentheses you pass something else to
  • 00:16:44 add event listener you pass the name of
  • 00:16:47 the function that should be executed
  • 00:16:48 eventually to that add event listener
  • 00:16:51 method you pass a pointer at this
  • 00:16:53 function object to add event listener
  • 00:16:56 and add event listener internally then
  • 00:16:59 we'll use this argument and the value
  • 00:17:01 stored in it so the function and call it
  • 00:17:04 for you when the time is right so in
  • 00:17:07 this case when I click OK and that's
  • 00:17:09 what I would like to call indirect
  • 00:17:11 function execution but this of course
  • 00:17:12 awls is a concept which is simply called
  • 00:17:14 callbacks we're using a callback
  • 00:17:17 function here we're passing a function
  • 00:17:19 as an argument to another function so
  • 00:17:21 that that our function can eventually
  • 00:17:24 call us back and call this function for
  • 00:17:27 us when the time is right and that's why
  • 00:17:31 we don't add parentheses here and how
  • 00:17:32 callback function
  • 00:17:33 work in the end now as with all the
  • 00:17:36 concepts below the video you of course
  • 00:17:38 find a more detailed resource on that
  • 00:17:40 this is just a brief summary of course
  • 00:17:42 because when it comes to for example pre
  • 00:17:45 configuring parameters add user should
  • 00:17:47 receive eventually you need to use
  • 00:17:50 certain tools like the bind method which
  • 00:17:52 is in JavaScript but again that's
  • 00:17:54 covered in the additional resources
  • 00:17:58 now we just saw callbacks in action one
  • 00:18:01 area where callbacks are typically used
  • 00:18:04 is the area of a synchronous code now
  • 00:18:08 javascript is single threaded which
  • 00:18:10 means it can only do one thing after
  • 00:18:12 another and setting a timer and then
  • 00:18:14 executing another part another piece of
  • 00:18:17 code works but maybe not in the way you
  • 00:18:20 would expect it to work because
  • 00:18:21 JavaScript when you set a timer does not
  • 00:18:24 pause code execution it only has one
  • 00:18:26 thread available to perform tasks to do
  • 00:18:29 work and it does not pause when you are
  • 00:18:31 setting a timer or sending a HTTP
  • 00:18:34 request because that would mean that
  • 00:18:36 your scripts are basically worthless if
  • 00:18:38 they can only do one thing at a time
  • 00:18:40 modern web applications where a lot of
  • 00:18:43 things happen simultaneously would just
  • 00:18:45 not be possible instead javascript
  • 00:18:48 offloads certain tasks to the
  • 00:18:51 environment it runs in like the browser
  • 00:18:53 with set timeout which is a function
  • 00:18:56 made available by the browser in the end
  • 00:18:58 it simply offloads the task of setting a
  • 00:19:02 timer to the browser and the browser
  • 00:19:04 also you could say memorizes the
  • 00:19:07 function the greet function here on the
  • 00:19:09 slide that should eventually be called
  • 00:19:11 when the timer completed so the browser
  • 00:19:14 manages the timer and JavaScript can
  • 00:19:16 continue do other things it can run our
  • 00:19:19 code synchronous code so code which
  • 00:19:22 finishes instantly and when the timer
  • 00:19:24 expired when the time is up the browser
  • 00:19:27 will notify JavaScript about this and
  • 00:19:29 tell it hey you gave me that greet
  • 00:19:31 function please execute it now and
  • 00:19:33 JavaScript will schedule this greet
  • 00:19:36 function to be executed as soon as
  • 00:19:38 possible so as soon as it has no other
  • 00:19:41 work left to do on its single thread
  • 00:19:44 that's how a synchronous code so code it
  • 00:19:47 takes a bit longer you could say works
  • 00:19:49 in JavaScript JavaScript performs task
  • 00:19:53 after task so setting a timer and
  • 00:19:56 console logging and this all happens
  • 00:19:59 basically instantly after another it
  • 00:20:01 does not wait for five seconds here
  • 00:20:03 instead it directly moves on to the next
  • 00:20:06 line and only executes say hello after
  • 00:20:09 five seconds because the timer is set
  • 00:20:11 and managed by the
  • 00:20:12 browser and it basically tells
  • 00:20:14 JavaScript when the time is up
  • 00:20:16 that's how asynchronous code works now
  • 00:20:20 callbacks are always important in
  • 00:20:22 asynchronous code but for more complex
  • 00:20:24 asynchronous code structures or snippets
  • 00:20:28 we also have the amazing feature of
  • 00:20:30 promises in modern JavaScript here's an
  • 00:20:33 example the fetch API is an API built
  • 00:20:36 into the browser and it sends a network
  • 00:20:38 request and get some data now when we
  • 00:20:40 get that response we often want to parse
  • 00:20:43 the data that's in the response and it
  • 00:20:45 turns out that in JavaScript as this API
  • 00:20:48 is set up this is another a synchronous
  • 00:20:50 task
  • 00:20:51 so this JSON method which basically
  • 00:20:53 parses the response data and gives us a
  • 00:20:55 JavaScript object does not finish
  • 00:20:57 instantly now if that fetch API which is
  • 00:21:00 built into the browser would use
  • 00:21:02 callbacks only and not this promise
  • 00:21:04 concept this might look something like
  • 00:21:06 this we have fetched we have a function
  • 00:21:09 that's executed when that fetch process
  • 00:21:11 has finished when we got a response in
  • 00:21:14 there we call Jason and to Jason we pass
  • 00:21:16 another function which is executed once
  • 00:21:18 the data has been parsed and if we do
  • 00:21:21 more and more asynchronous work we have
  • 00:21:23 a deeper and deeper nesting that's
  • 00:21:25 called callback hell because it can
  • 00:21:27 quickly get quite hard to read
  • 00:21:29 now promises work differently a promise
  • 00:21:32 is simply a JavaScript object that has a
  • 00:21:34 ven and a catch method and fetch return
  • 00:21:37 such a promise we can basically call the
  • 00:21:41 then method to set up a function that
  • 00:21:43 should be triggered that should be
  • 00:21:44 executed when the promise resolves so
  • 00:21:48 when it's done with its work now the
  • 00:21:50 trick is that every then method then by
  • 00:21:53 default returns a new promise or if we
  • 00:21:56 return a separate promise as we do here
  • 00:21:58 jason also yields a promise that default
  • 00:22:01 promise is replaced by that return
  • 00:22:04 promise so long story short then always
  • 00:22:06 yields a promise object itself which is
  • 00:22:09 why we can chain then calls we can call
  • 00:22:12 then after then because then yields a
  • 00:22:15 new promise and this allows us to set up
  • 00:22:17 steps of code that executes after each
  • 00:22:20 other
  • 00:22:20 first we wait for the response we start
  • 00:22:23 the data parsing process and
  • 00:22:25 that finished this code here this
  • 00:22:27 function here execute and error handling
  • 00:22:31 is also easy we can add a catch method
  • 00:22:34 in this chain here because every promise
  • 00:22:36 does not just have then but also catch
  • 00:22:38 and catch will trigger this function
  • 00:22:41 when any prior promise fails so this
  • 00:22:44 promise or this promise or the main
  • 00:22:46 fetch promise if any of those free
  • 00:22:49 promises fails this function here will
  • 00:22:51 execute
  • 00:22:52 that's how promises work and of course
  • 00:22:55 there's a bit more to them in my
  • 00:22:58 JavaScript the complete guide course as
  • 00:23:00 well as in the JavaScript the tricky
  • 00:23:02 parts course I dive a bit deeper into
  • 00:23:04 them here the key take away is how
  • 00:23:07 asynchronous code generally works that
  • 00:23:09 tasks are offloaded to the browser and
  • 00:23:12 that we have callbacks and basically the
  • 00:23:15 enhanced version of callbacks promises
  • 00:23:17 to then orchestrate our code steps our
  • 00:23:21 code snippets that should be executed
  • 00:23:23 when such tasks finish
  • 00:23:27 okay you probably waited for it one of
  • 00:23:31 the most tricky things in JavaScript is
  • 00:23:34 that this keyword it can really behave
  • 00:23:37 strangely and here's an example when I
  • 00:23:39 call output info I in the end call this
  • 00:23:42 print age method because I stored a
  • 00:23:44 print H method in output info in line
  • 00:23:46 eight so we would expect to lock the age
  • 00:23:49 of the person here right because that's
  • 00:23:51 what I'm referring to in line 4 which is
  • 00:23:53 in that method that's being called
  • 00:23:55 however if I reload this in the browser
  • 00:23:58 we see undefined instead of the age and
  • 00:24:01 Dad simply happens because of the way
  • 00:24:04 that this keyword works this unlike in
  • 00:24:08 other programming languages does not
  • 00:24:10 always refer to the object it's it's
  • 00:24:13 written in you could say instead this
  • 00:24:15 and that's a good rule of thumb refers
  • 00:24:18 to who called a function if you're using
  • 00:24:22 this it only matters about the functions
  • 00:24:25 being used in and who called that
  • 00:24:27 function and if we for example do person
  • 00:24:31 print age you will see that we get this
  • 00:24:34 age output here and the reason for that
  • 00:24:36 is that we call print age on person so
  • 00:24:39 person called dead function you could
  • 00:24:41 say and therefore this inside of print
  • 00:24:44 age refers to that when we call output
  • 00:24:47 info like this you could say no one
  • 00:24:49 called that function or that function is
  • 00:24:52 called on nothing and therefore this
  • 00:24:55 inside of the function refers to not
  • 00:24:58 nothing but actually to the global
  • 00:25:00 window object that is you could say it's
  • 00:25:03 it's fallback if it's not called on
  • 00:25:05 anything else and that really is the
  • 00:25:08 most important thing to memorize about
  • 00:25:10 this when you think about what this
  • 00:25:13 refers to you should look at the
  • 00:25:15 function that's being called and how
  • 00:25:18 it's being called and if it's called on
  • 00:25:20 something this will refer to that
  • 00:25:22 something if it's called like this this
  • 00:25:26 will not refer to the object it might be
  • 00:25:29 Whiston but simply to something else
  • 00:25:31 typically to the global window object so
  • 00:25:34 looking at who called something and how
  • 00:25:36 it's called is the key to understanding
  • 00:25:39 this now there still are
  • 00:25:41 some special cases like having an
  • 00:25:44 anonymous function in an eventlistener
  • 00:25:46 where this will not refer to the window
  • 00:25:48 object but to the elements that caused
  • 00:25:51 the event but that's covered in the
  • 00:25:53 additional resources below the video if
  • 00:25:55 you want to dive into that the key
  • 00:25:57 takeaway is that rule of thumb that you
  • 00:25:59 look at who called a function or on what
  • 00:26:02 a function is called and dead this then
  • 00:26:05 refers to that what
  • 00:26:10 now the last tricky thing I wanna dive
  • 00:26:12 in in this video are prototypes
  • 00:26:15 prototypes are an essential part of
  • 00:26:17 JavaScript
  • 00:26:18 they are the key concept when it comes
  • 00:26:21 to inheritance in JavaScript and yet
  • 00:26:23 prototypes can be hard to understand and
  • 00:26:26 to reason about and the name is part of
  • 00:26:28 that prototype sounds like blueprint at
  • 00:26:31 least to me but a prototype in
  • 00:26:34 JavaScript is actually more of a
  • 00:26:35 fallback object and that's the core idea
  • 00:26:38 of prototypes every object in JavaScript
  • 00:26:41 has a prototype and you either get a
  • 00:26:44 default prototype if you create an
  • 00:26:45 object like this then the default
  • 00:26:48 prototype is object dot prototype more
  • 00:26:51 on that in a second or you create an
  • 00:26:54 object for example like this with the
  • 00:26:56 create method on the object constructor
  • 00:26:59 function and you can set the prototype
  • 00:27:01 of the to be created object to some
  • 00:27:03 other object in this case user has
  • 00:27:05 person as a prototype and the
  • 00:27:08 consequence is that if we access a
  • 00:27:10 property on user which doesn't exist
  • 00:27:12 directly on user javascript has a look
  • 00:27:15 at its prototype and the prototype of
  • 00:27:17 user which is person does have that kind
  • 00:27:19 property and that's really the essence
  • 00:27:22 of prototypes prototypes are fallback
  • 00:27:25 objects in JavaScript you can set them
  • 00:27:28 when you create an object like this you
  • 00:27:30 can change them after an object has been
  • 00:27:32 created with set prototype off for
  • 00:27:35 example and you can also set them on
  • 00:27:38 constructor functions here we have the
  • 00:27:41 person constructor function and there we
  • 00:27:44 have that special prototype property
  • 00:27:46 which is often misunderstood using that
  • 00:27:50 prototype property which exists on every
  • 00:27:53 function object in JavaScript does not
  • 00:27:56 set the prototype of this person
  • 00:27:59 constructor function object instead we
  • 00:28:02 set the prototype of to be created
  • 00:28:05 objects that are created based on this
  • 00:28:08 constructor function so by executing the
  • 00:28:10 constructor function with the new
  • 00:28:12 keyword so max here has human as a
  • 00:28:15 prototype as a fallback object because
  • 00:28:19 the constructor function is
  • 00:28:20 pre-configured to give it that prototype
  • 00:28:23 that's what the prototype property does
  • 00:28:26 if you want to find out which prototype
  • 00:28:29 an object has you can use the underscore
  • 00:28:32 underscore proto underscore underscore
  • 00:28:34 property this is a non-standard property
  • 00:28:37 which means it's not part of the
  • 00:28:39 JavaScript standard but most browsers
  • 00:28:41 support it and this gives you the
  • 00:28:43 prototype of an object it's nice for
  • 00:28:47 analyzing your code it's nice during
  • 00:28:49 development but otherwise not a property
  • 00:28:51 you should really use instead this year
  • 00:28:54 this prototype property allows you to
  • 00:28:56 pre-configure prototypes on constructor
  • 00:28:59 functions and you got the aberrant
  • 00:29:01 methods you saw before for setting and
  • 00:29:03 changing prototypes in addition in
  • 00:29:05 modern JavaScript you also got the class
  • 00:29:07 keyword and the extends keyword to
  • 00:29:11 extend another class so to have
  • 00:29:14 inheritance and under the hood this also
  • 00:29:16 uses prototypes but I dive deeper into
  • 00:29:18 that in my tricky parts course the
  • 00:29:21 essence of prototypes is that their
  • 00:29:24 fallback objects Java Script uses to
  • 00:29:27 look up missing functionalities and if
  • 00:29:30 you wonder why we have that let's have a
  • 00:29:32 look at an array one two three a simple
  • 00:29:35 array of numbers now that's a
  • 00:29:37 straightforward array and if I log it
  • 00:29:39 it's not too exciting what we see here
  • 00:29:41 but we actually see something
  • 00:29:43 interesting if we take a closer look
  • 00:29:45 this array object arrays are objects
  • 00:29:48 after all has free keys 0 1 2 & 1 extra
  • 00:29:53 keep the length key okay that's all nice
  • 00:29:55 that's what is created when you create
  • 00:29:57 an array what you don't see in this
  • 00:30:00 object however are all those array
  • 00:30:02 methods like push or map or filter and
  • 00:30:06 you of course know that those methods
  • 00:30:08 exist on arrays now they're not part of
  • 00:30:11 every array object because dad would
  • 00:30:14 take up a lot of space in memory if you
  • 00:30:16 work with a lot of arrays in your code
  • 00:30:18 and every array has all those methods no
  • 00:30:22 matter if you use them on this array or
  • 00:30:24 not that's a lot of extra stuff to store
  • 00:30:27 and to manage and that's not great for
  • 00:30:29 memory and for performance therefore
  • 00:30:31 instead a newly created array has a
  • 00:30:34 special prototype a special fall bag
  • 00:30:37 object which then has all those methods
  • 00:30:40 so which has push and pop and all those
  • 00:30:42 array methods and every array has that
  • 00:30:45 same prototype object so that utility
  • 00:30:49 object with all those methods is only
  • 00:30:52 created once it's only stored in memory
  • 00:30:54 once and then every array is just linked
  • 00:30:57 to it through that prototype concept and
  • 00:31:00 that's why we have prototypes it makes
  • 00:31:02 managing code easier and allows us to
  • 00:31:05 for example optimize memory and
  • 00:31:08 performance