Lecturer: Maybe it didn't seem like it
but hoisting is actually a fairly straightforward process.
So let's just go through the different scenarios here
starting with variables.
So let's just create three variables here
using the three different ways of declaring them.
So now let for the job, teacher
and then const for the birth year
let's just call it year 1991.
And now let's try to use
all of these three variables
before declaring them, just to see what happens.
So me, job and year.
So from the rules that we learned
in the previous lecture,
what do you expect will happen now?
Well, the first console dot log result in undefined,
and that's because variables declared
with var are actually hoisted,
but they are hoisted to the value of undefined.
And so therefore when we try to access them
undefined is exactly the result that we get.
And so that's the reason why we see this here.
Then on the contrary we have this let variable,
and so here we see that we cannot
access job before initialization.
And so that's exactly the kind of error
that I showed you in the last slide.
And the origin of this error
is the fact that the job variable is still
in the temporal dead zone here at this point.
Right, so remember that the temporal dead zone
of a variable declared with a let or const,
starts from the beginning of the current scope
and so that's basically here,
so in this case, it's the global scope.
So from the beginning of the scope
until the point of the code where it is defined
and so here.
And this means that at this point of course,
the job variable is still in the temporal dead zone,
and the same is true for year.
And so now we get the same error here
for the year variable as well.
All right, so let's comment out both of these.
Let me just right here
that is hoisting with variables
and now let's try out functions.
So let's create a function declarations
and function expressions here.
So function, and again I will use a simple add
let me just call it, addDecl,
which stands for declaration a, b
and return a plus b,
and now a function expression.
So addExpression, at once more return a plus b.
And now since we're doing these two,
let's also create an arrow.
So addArrow, a, b and return a plus b implicitly.
So I hope you remember
that this is how the arrow function works.
And now once again
let's try to use these functions,
before they are defined.
And so I will log them to the console,
so the result of calling them
because they returned something,
and so we need to log the result to the console
so as you already know.
So let's add two plus three,
and now what do you think will happen?
Do you think that it will be undefined again
just like we have here with the var variable?
Let's see.
And no, we actually get the result of five.
And so indeed we were able
to call the function declaration
before it was actually defined here in the code.
All right, and now let's try the same
for the other two expression and addArrow,
but now I hope that you can already
anticipate what is gonna happen.
And so indeed we get an
cannot access addExpression before initialization.
And so that's exactly the same error
that we got before here
with this let and const variables.
And that's because this function here right now
is simply a const variable too.
And so it means that it's now also
in the temporal dead zone right?
So again we are simply assigning
a function value to this variable.
And since this variable was defined with const,
it is now in a temporal dead zone
and therefore we get this exact
same error message as before.
And the same of course
is gonna happen with the arrow, right?
But now let me show you what happens
when we change these to var.
So do you think that now it will work somehow?
Okay, we still get an error,
but it is another error message here.
So right now addExpression is not a function.
And once again
the same is gonna be happening for the arrow.
Okay, and now let's think about the reason
for this different error message here.
So as you already know, any variables declared
with var will be hoisted and set to undefined.
And now this addExpression here is essentially that,
it's a variable declared with var
and so right now it is undefined.
And then here we are trying
to call undefined basically.
So we are doing essentially this so undefined
and then we are trying to call it.
And so we should not get the exact same error.
So you see it's not a function.
And in fact, let me show it
to you here even better.
So addArrow should now be undefined,
and indeed, here it is.
And once more that is because
we now declared these two here with var.
Okay, so let's simply take both of these out
and for you to keep this as a reference,
I will leave this one as a var
and this as a const,
but just know that both of them will not work.
The only function that you can use
before declaring it, is the add function declaration.
Okay. So now we covered all the rules here
and saw how hoisting works.
But now let's show me a very cool example
which can demonstrate a pitfall of hoisting.
And so it's a mistake that we can easily make
if we're not careful
and at the same time use var,
to declare our variables.
So let's just write example here.
So to start, let's declare a fictional function here,
so a function which is a function declaration,
and that's important.
So a fictional function that will delete
the shopping cart.
So let's say that we have
like an eCommerce website or application.
So let's simply log here, all products deleted.
And so this is a dangerous function
okay, that we should not be calling without care.
Next, let's also declare a variable
which contains the number of products.
And so now I will use a var
and this will then show you once more
why we should not use var products equals 10.
And now here at the top of our code,
we are going to write some logic
which will delete the shopping cart,
whenever the number of products is zero.
Now we already know that zero is a false value
and so we can write this, right?
So in this case, we want to call,
deleteShoppingCart now right?
So again, here we have var numProducts set to 10,
but then here we have this logic
in which we want to write that
when there is no products,
we want to delete the shopping cart.
But now what would actually happens?
So we get all products deleted
even though numProducts is actually 10.
So why did that happen?
Well, it is because of hoisting.
So at this point of the code here,
the numProducts variable is in fact,
not 10 instead, what is it?
Well, it is undefined.
And that's because of the way hoisting works
with var variables.
So we just show that to you very quickly,
and so indeed, now here from line 71,
which is this one, we get this undefined.
And we know that undefined is also a false value,
and so therefore, this code will instill execute
even though we thought that numProducts is 10,
but in fact, it's undefined,
and so that will also trigger the execution
of this if block here.
Now of course,
this is just a fictional tiny example
but in a large code base
with thousands of lines of code
and without best practices,
something like this can totally happen
and it's gonna be a bug,
that will be hard to find.
So what are these best practices?
What is the conclusion of all this?
Well, as a first step, as I told you many times
just don't use var to declare variables.
Use const most of the time to declare variables
and let, if you really need to change
the variable later.
Also in order to write clean code,
you should declare your variables
at the top of each scope.
That will just make your code
at least look a little bit better.
Finally, always declare all your functions first
and use them only after the declaration.
And this applies to all types of functions,
even function declarations, which are hoisted.
So you could use function declarations
before you declare them,
but still just don't do that it's just not clean.
Okay, so what I just told you
are the best practices,
not the rules of how it works in JavaScript.
All right, and now just to finish,
since we're talking about the differences
between let, const and var here,
let's just take two minutes
to see yet another small difference between them.
So let's again declare one variable for each
let y equals two.
So the values don't matter at all here.
And now let's just take a look
at the window object in the console.
Okay, x has been out of course, z here,
and so let's now take a look here
at the window object here in the console.
And window is the global object
of JavaScript in the browser.
And you can see all kinds of stuff in here,
for example, the alert window
that we have used before
or also some other functions
that we probably might have used already before.
So I'm not gonna go into that here,
but what is important,
so let's go all the way to the down here
and you can of course explore this by yourself
in case you're interested in,
but what matters here
is that besides all these functions,
we also get a property of x equals one.
And that's exactly the variable
that we declared right here using the var keyword.
However, we cannot find y or z here
anywhere in this object.
And that's because they were declared
with let or const.
And so variables declared that way
do not create properties on the window object.
So let me actually demonstrate this to you even better.
So we can say or we can test,
x equal, equal, equal window dot x.
So here we are testing if x
is actually a property of the window object.
And so if it is, then of course
x must be the same as window dot x.
And actually it is true.
And now the same for y and z,
and so in these cases, it is both false.
So in conclusion I just wanted to let you know
that variables declared with var,
will create a property
on the global window object.
And that can have some implications in some cases.
And again, you can take some time
to explore the window object
because it's quite interesting to see
everything that is in there.
All right, but with that being said
let's now finally move on to our next topic
which is gonna be the disc keyword.