var的变量提升
var声明的变量会被提升到其作用域的顶部,并使用 undefined 值对其进行初始化.
alert(greeter);
var greeter = 'say hello';
//前面的代码会被解析为:
var greeter;
alret(greeter); // greeter is undefined
greeter = 'say hello';
let声明的变量
let 是块级作用域,声明的变量保持常量值就像var一样,用let声明的变量可以在其范围内被修改。但与var不同的是,let变量无法在其作用域内被重新声明。用let声明的变量同样会被提升到其作用域的顶部,但不会对值进行初始化,因此,如果你尝试在声明前使用let变量,则会收到Reference Error的报错。
//let变量无法在其作用域内被重新声明:
let greeting = 'say Hi';
greeting = 'say Hei instead';
let greeting = 'say Hello instead'; // error: Identifier 'greeting' has already been declared
如果在不同的作用域中定义了相同的let变量,则不会有错误。
//不同的作用域中定义了相同的let变量,不会有错误:
let greeting = 'say Hi';
if (true) {
let greeting = 'say Hello instead';
console.log(greeting); // "say Hello instead"
}
console.log(greeting); // "say Hi"
const 声明的变量
const 是块级作用域,声明的变量保持常量值,不能被修改并且不能被重新声明,因此,每个const声明都必须在声明时进行初始化。
//const变量保持常量值,不能被修改并且不能被重新声明:
const greeting = 'say Hi';
greeting = 'say Hello instead'; // error: Assignment to constant variable.
const greeting = 'say Hello instead'; // error: Identifier 'greeting' has already been declared
虽然不能更新const对象,但是可以更新该对象的属性。
const greeting = {
message: 'say Hi',
times: 4,
};
//正确的修改:
greeting.message = 'say Hello instead';
//错误的修改:
const greeting = {
words: 'Hello',
number: 'five',
}; // error: Assignment to constant variable.
最后,我们总结一下它们的异同:
- var声明是全局作用域或函数作用域(看你声明在哪里,声明在函数外就是全局),而let和const是块作用域。
- var变量可以在其范围内更新和重新声明; let变量可以被更新但不能重新声明; const变量既不能更新也不能重新声明。
- 它们都会被提升到其作用域的顶端。但是只有var变量会用“undefined”初始化,不会初始化let和const变量。
- 可以在不初始化的情况下声明var和let,但是在声明期间必须初始化const。