let
块级作用域
let声明的变量, 有块级作用域,只能在大括号{}里使用
好处: 避免全局变量污染
// 块级作用域
// 在大括号内, 用let声明的变量, 只能在大括号内使用
if (true) {
    let myName = "Liao"
    console.log(myName) //Liao
}
 console.log(myName) //myName is not defined
先定义再使用
let必须先定义再使用, 不然就会报错
  console.log(a) // 报错
  let a = 10
不可重复声明
let同一个作用域下, 不能重复声明同一个名字的变量
let a = 10
let a = 10 // 报错
全局let不会挂载到window上
避免污染window原有的全局变量
const
作用: 声明常量
必须赋予初始值, 且无法修改
其他特点和let相同
- 块级作用域
 - 不挂载到 window 上
 - 必须先声明再使用 (没有变量声明提升)
 - 同一个作用域下, 不能重复声明同一个名字的变量
 
注意
const声明的变量, 如果存复杂类型, 存的是对象/数组的内存地址
只要地址不改变, 可以修改指向的对象或者数组的内容
const obj = {
  name: 'Liao',
  age: 18
}
// obj = {} // 报错,常量不能修改
obj.name = 'lll' // 正确
var
var没有块级作用域, 容易造成变量污染
全局的var会被自动挂载到 window 上, 污染 window 的变量(这不合理!)
var a = 10
console.log(window.a) //10
var存在变量声明提升, 先使用后定义不报错! 会打印 undefined(这不合理!)
console.log(a) // undefined
var a = 10
var就算同一个作用域下, 重复声明了相同的变量名, 也不报错(这不合理!)
var a = 10
var a = 20
var总结
- 没有块级作用域
 - 全局的
var会污染 window 的变量 - 先使用后定义不报错
 - 同一个作用域下, 重复声明了相同的变量名, 也不报错