var声明提升
var关键字声明的变量会自动提升到函数作用域顶部:
function foo() {
console.log(age);
var age = 26;
}
foo(); // undefined
之所以不会报错,是因为 运行时,等价于
function foo() {
var age;
console.log(age);
age = 26;
}
foo(); // undefined
所谓的“提升”,也就是把所有变量声明都拉到函数作用域的顶部。此外,反复多次使用var
声明同一个变量也没有问题。
let声明,没有提升
let
声明的范围是块作用域,而var
声明的范围是函数作用域。
let
也不允许同一个块作用域中出现多次声明。
JavaScript引擎会记录用于变量声明的标识符及其所在的块作用域,因此嵌套使用相同的标识符不会报错,而这是因为同一个块中没有重复声明:
var name = 'Nicholas';
console.log(name); // 'Nicholas'
if (true) {
var name = 'Matt';
console.log(name); // 'Matt'
}
let age = 30;
console.log(age); // 30
if (true) {
let age = 26;
console.log(age); // 26
}
使用let
在全局作用域中声明的变量不会成为window
对象的属性(var
声明的变量则会)
for
循环中的let
声明
for (var i = 0; i < 5; ++i) {
setTimeout(() => console.log(i), 0)
}
// 你可能以为会输出0、1、2、3、4
// 实际上会输出5、5、5、5、5
for (let i = 0; i < 5; ++i) {
setTimeout(() => console.log(i), 0)
}
// 会输出0、1、2、3、4
const声明, 没有提升
const
的行为与let
基本相同,唯一一个重要的区别是用它声明变量时必须同时初始化变量,且尝试修改const
声明的变量会导致运行时错误。
const age = 26;
age = 36; // TypeError: 给常量赋值
// const也不允许重复声明
const name = 'Matt';
const name = 'Nicholas'; // SyntaxError
// const声明的作用域也是块
const name = 'Matt';
if (true) {
const name = 'Nicholas';
}
console.log(name); // Matt
const
声明的限制只适用于它指向的变量的引用。那么如果const
变量引用的是一个对象,是可以修改这个对象内部的属性的。