var
var a; // 未初始化则为undefined
/* var作用域在函数块内 function scope */
function test() {
var message = "hi"; // local variable
}
test();
console.log(message); // error!
/* 不用var声明的是全局变量,不推荐使用 */
function test() {
message = "hi"; // global variable
}
test();
console.log(message); // "hi"
/* var变量提升 Declaration Hoisting */
console.log(age); // undefined
var age = 26;
/* var可重复声明 */
var age = 16;
var age = 26;
var age = 36;
console.log(age);
let
/* let 是块级作用域 block scoped */
if (true) {
let age = 26;
console.log(age); // 26
}
console.log(age); // ReferenceError: age is not defined
/* let 不可重复声明 */
let age;
let age; // SyntaxError; identifier 'age' has already been declared
/* let 没有变量提升 */
/* 混合使用 */
let name = "a"
var name = "b" // Identifier 'name' has already been declared 因为var有变量提升
全局声明
声明全局变量时,var会把变量挂到window对象上,let不会
var name = 'Matt';
console.log(window.name); // 'Matt'
let age = 26;
console.log(window.age); // undefined
let 在for循环
for (var i = 0; i < 5; ++i) {
setTimeout(() => console.log(i), 0)
}
// 5 5 5 5 5
var声明的是同一个变量,for循环结束后,setTimeout里的函数传入的是同一个 i
for (let i = 0; i < 5; ++i) {
setTimeout(() => console.log(i), 0)
}
// console.logs 0, 1, 2, 3, 4
用let,每次for循环都会声明一个新的变量,每个setTimeout调用的都是对应的块里的i
const
/* const声明必须初始化赋值 */
const age = 26;
/* const声明的变量不能修改赋值 */
/* const和let一样是块级作用域 */
/* const声明的变量不会挂到window上 */
/* 用const声明一个对象,并修改其属性是可以的 */
const person = {};
person.name = 'Matt';
/* 不能用const声明for循环里的迭代器iterator */
for (const i = 0; i < 10; ++i) {}
/* 不会改值的for循环是可以的 */
for (const key in {a: 1, b: 2}) {
console.log(key);
}
总结
- 不要用var
- const 优于 let