我认为 js 中的变量是有生命周期的: 声明->初始化->赋值->销毁。当然,赋值阶段是可以不断重新赋值的。
var 的变量提升
1 2 3 4 5 6 7 8 9
| console.log(a); var a = 1; console.log(a);
(declare a) && (a = undefined); console.log(a); a = 1; console.log(a);
|
let 的块级作用域
1 2 3 4 5
| console.log(a); let a; console.log(a); a = 1; console.log(a);
|
上面这段代码是没办法执行的,因为第一行已经报错了。如果我们将它 catch 住,继续执行后面的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| try { console.log(a); } catch (e) { console.log(e); } let a; console.log(a); a = 1; console.log(a);
declare a; try { console.log(a); } catch (e) { console.log(e); } a = undefined; console.log(a); a = 1; console.log(a);
|
结论
通过以上两个对比,能看出来不管是 var or let,都存在变量提升。区别是:
- var 会将变量的声明和初始化一并提升至作用域头部。
- let 仅将变量的声明提升至作用域头部。
然后再看看下面这两个例子,应该差不多就懂了:
1 2 3 4 5 6
| var name = "Alice"; function sayName() { console.log(name); let name = "Bob"; } sayName();
|
1 2 3 4 5 6
| let name = "Alice"; function sayName() { console.log(name); var name = "Bob"; } sayName();
|