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); // undefinedvar 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
