1var is function scoped and let is block scoped. Let's say you have:
2function understanding_var() {
3 if (1 == 1) {
4 var x = 5;
5 console.log('the value of x inside the if statement is ' + x);
6 }
7 console.log(x);
8}
9//output: the value of x inside the if statement is 5
10 5
11
12function understanding_let() {
13 if (1 == 1) {
14 let x = 5;
15 console.log('the value of x inside the if statement is ' + x);
16 }
17 console.log(x);
18}
19//output: the value of x inside the if statement is 5
20 Uncaught ReferenceError: x is not defined
21
22var is defined throughout the entire function, even if it's inside the if
23statement, but the scope of let is always within the curly braces, not outside
24it, even if the conditional statement is inside the function.
1let a = 'hello'; // globally scoped
2var b = 'world'; // globally scoped
3console.log(window.a); // undefined
4console.log(window.b); // 'world'
5var a = 'hello';
6var a = 'world'; // No problem, 'hello' is replaced.
7let b = 'hello';
8let b = 'world'; // SyntaxError: Identifier 'b' has already been declared
1// var is function-scoped, so redeclaring it in a block will cause its value outside the block to change as well:
2
3var one = 'one: declared outside the block';
4
5if (true === true) {
6 var one = 'one: declared inside the block'; // notice: we redeclare 'one' here
7 console.log(one); // prints 'one: declared inside the block'
8}
9
10console.log(one); // also prints 'one: declared inside the block', because the variable was redeclared in the 'if' block. The outer 'var' variable was therefore destroyed and replaced by inner var variable.
11
12// 'let' is block-scoped, so redeclaring a 'let' variable inside of a block creates a different 'let' variable with the same name whose scope is inside the block:
13
14let two = 'two: declared outside the block';
15
16if (true === true) {
17 let two = 'two: declared inside the block';
18 console.log(two); // prints 'two: declared inside the block'
19}
20
21console.log(two); // prints 'two: declared outside the block', because two declared inside the block is a separate variable. The 'let' variables are unrelated and therefore are unaffected by each other.