let声明
声明变量的三种方式:var、let、const,其中let和const为ES6新增
let与var的作用差不多,但存在着一些区别
1、 作用域(最显著的区别)
let声明的范围是块作用域,var声明的范围是函数作用域

Let声明的变量的作用域被限制在块中,即一对花括号中
2、 暂时性死区
var声明的变量存在“变量提升”,而let不存在“变量提升”。
变量提升:JavaScript 引擎的工作方式是,先解析代码,获取所有被声明的变量,然后再一行一行地运行。这就使得所有的变量声明语句,都会被提升到代码的头部,这就叫做变量提升
var声明的变量会被自动提升到函数作用域顶部,因此上面代码不会报错,输出的是undefined,而换成let,由于其不存在“变量提升”所以会直接报错。
在代码块内,使用let命令声明变量之前,该变量都是不可用的,这被称为“暂时性死区”,即在let声明age变量之前,都属于age变量的“死区”
3、 全局声明
使用let在全局作用域中声明的变量不会成为window对象的属性(var声明的变量则会)
4、 重复声明
let不允许在相同作用域内,重复声明同一个变量(var重复声明会被忽略,当成赋值语句)
Const声明
const与let基本相同,唯一的区别在于const声明变量时必须同时初始化,且一旦声明,常量的值就不能改变,尝试修改会报错
本质:const实际上保证的是const变量所指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的,至于它指向的数据结构是不是可变的,就完全不能控制了。换句话说,如果const变量引用的是一-个对象,那么修改这个对象中的属性并不违反const的限制。(指针不发生改变)
如果想将对象冻结,应该使用Object.freeze方法。
总结
let和const与var的区别在于块作用域、不存在变量提升、不能重复声明以及不会成为window的属性。最佳实践:不使用var,const优先,let次之。使用const声明可以让浏览器运行时强制保持变量不变,也可以让静态代码分析工具提前发现不合法的赋值操作。只在提前知道未来会有修改时,再使用let。