The comparison between Var and let in JavaScript is a commonplace problem. Let's talk about these two keywords today
Variable lifting
First of all, the variables are upgraded. var can be upgraded, but let can't. I think that's a good thing.
When it comes to variable promotion, let's talk about function
function test() {
console.log('a')
}
test ()
function test() {
console.log('b')
}
test()
// output b b
var test = 1
function test() {
console.log('a')
}
test ()
// TypeError: test is not a function
// Equivalent to the following code
var test
function test() {
console.log('a')
}
test = 1
test()
This involves the difference between the variable promotion of function and var. the variable promotion in var only promotes the variable declaration and does not assign the initial value in advance, but function points to that function when it is promoted, so function is obviously more confusing
Here someone may ask about the sequence of variable promotion and function promotion. In fact, I think it doesn't matter who is the first and who is the second. Because var keyword promotion only declares no assignment and can be repeated, so no matter who is the first and who is the second, the final expression can write function at the end. You may need to think about this
Block level scope
{
var a = 1
let b = 2
}
console.log(a)
console.log(b)
// output:
// 1
// ReferenceError: b is not define
The variables declared by let only exist in the block level scope, so the following code
for (let i = 0; i < 10; i++) {
setTimeout(() => {
console.log(i)
}, 1000)
}
// output: 0123456789
Why? Because each cycle variable i is different. Unconvinced? Let's verify
let map = {}
for (let i = 0; i < 10; i++) {
map[i] = {
add() {
i++
},
print() {
console.log(i)
}
}
}
map[0].print()
map[1].print()
map[0].add()
map[0].print()
map[1].print()
// output: 0 1 1 1
We use closures to keep these variables from being recycled. Although they are all i, they are different
Temporary dead zone
Variables declared by let are not allowed to be declared again or used before declaration (not only because variable promotion is not allowed)
{
let a = 1
b = 2
var a = 3 // SyntaxError: Identifier 'a' has already been declared
}
{
console.log(b)
console.log(a) // a is not define
let a = 1
var b = 2
}
{
console.log(typeof b)
console.log(typeof a) // a is not define
let a = 1
}
The difference between Nodejs and browser
Observe the difference between the following code in Nodejs and browser
{
let a = 1
b = 2
var c = 3
debugger
}
/*
Nodejs
BecauseletThe declared variable has Block level scope, so a is under Block
Since b is not declared, the default binding isgloballower
c UsedvarIt is declared and does not have block level scope, so it is bound under the Local module
*/
/*
Browser
BecauseletThe declared variable has Block level scope, so a is under Block
Because b is not declared, the default binding isglobalIn the browserwindow
c UsedvarDeclaration does not have block level scope, and there is no module in the browser, so it is bound toglobalIn the browserwindow
*/
Nodejs medium
Browser
d = 6
var e = 4
let f = 5
debugger
/*
Nodejs
Since d is not declared, the default binding isgloballower
e UsevarDeclaration, so it is bound under local
f UseletDeclaration, also bound under local
*/
/*
Browser
Since d is not declared, the default binding isglobalIn the browserwindow
e UsevarDeclaration, there is no module in the browser, so it is also bound inglobalIn browserwindow
f UseletStatement, andletDeclared variables are not bound to theglobalSo f is bound to Script
*/
Nodejs medium
Browser