var x = true;
if (x == true) {
console.log(typeof(x));
let x = false;
};
console.log(x);
Sorry new to programming and getting this error: Error: x is not defined.
I am extremely confused.
var x = true;
if (x == true) {
console.log(typeof(x));
let x = false;
};
console.log(x);
Sorry new to programming and getting this error: Error: x is not defined.
I am extremely confused.
It doesn't look like it, but the two variables you declared are different. Your var
declaration is one of them, and the let
declaration is different. You've confused yourself by naming them with the same variable.
The let x
exists strictly within the if
block. This let x
is the only x
that can exist in that block now and you've tried to use that x
before you declared it when you attempt a console.log
.
You can get away with using variables before you declare them with var
, but let and const won't let you.
Also, I highly recommend you don't mix var
and let
in your code. You have to really understand what's going on if you do.
var x = true; // first x variable
if (x == true){ // first x variable
console.log(typeof(x)); // second x variable, used before declaration
let x = false; // second x variable created in `if` block
};
console.log(x); // first x variable
edit: Your follow up question is still 2 different variables. The only thing you've done is coerced the code to make it look EVEN MORE like the same variable.
var x = true; // first x
if (x == true) { // first x
let x = false; // second x
console.log(x); // second x, false
};
console.log(x) // first x, true
This one's a little tricky to explain, but I'll try;
var x = true;
if (x == true) {
console.log(typeof(x)); // <-- Error: x is not defined.
let x = false;
};
console.log(x); // true
The last line is actually fine because you defined x
up top.
What's happening inside the if
statement is that JavaScript looks ahead and sees that you've declared x
(with let
or const
) somewhere in that scope, but it hasn't yet reached that line.
So merely having a let
or const
somewhere further down in the same scope is causing that variable to not be defined.
If you move it up a line, everything is fine:
var x = true;
if (x == true) {
let x = false;
console.log(x); // false
};
console.log(x); // true
And if you don't redeclare x
, it's also fine:
var x = true;
if (x == true) {
let y = false; // different variable name (won't "shadow" the `x` from above)
console.log(x,y); // true false
};
console.log(x); // true
var
behaves differently:
if (true) {
console.log(y); // undefined
var y = false; // `var` is less strict. The declaration of `y` is hoisted to the top of the scope, but it's not assigned until this line
console.log(y); // false
};
The part of explanation that everyone is missing is that declarations are hoisted, which means that the declaration is brought to the beginning.
This is especially true with var
. For let
things are a little bit different and the term hoisting is not the most accurate. But it is useful to understand what is going on.
When executed, your code will look something like this (not exactly but gives the idea)
var x = true;
if (x == true) {
let x // hoisted at top of scope, for let scope is this if block
console.log(typeof(x));
x = false;
};
console.log(x);
Now everything should make sense: typeof(x)
refers to the x
declared with let
but not yet initialized.
To be clearer this is the reason why the x
inside of typeof
refers to the x
declared in the row below and not the one at the beginning: because the declaration of the existence of x inside that block is brough to the beginning of such block