异同之处
1:var 和 let 声明的是变量,可更改值,const 不可,
2:var 声明的变量只具有函数作用域, let 和 const 声明的变量和常量具有块级作用域
3:ar 和 let 变量的声明可以不做赋值操作,const 不可,
4:let 不可以重复声明一个变量,重复声明会报错,var 则不会
5:let 不存在变量提升,var存在
var
var 存在全局作用域和函数作用域两种。没有块级作用域的说法,并且存在变量提升。
let
1.块级作用域{}
- 作用域只在他所在的代码块
- 一个 {}可以看作一个作用域
- if语句和 for语句里面的{ }也属于块作用域
- 很适合在for循环中使用
- 在作用域之外 i 不能被访问。从上面for循环的中可以看出,设置变量那一部分是一个作用域,循环体内部是一个单独的作用域。
- 在作用域之外 i 不能被访问。从上面for循环的中可以看出,设置变量那一部分是一个作用域,循环体内部是一个单独的作用域。
- 为什么会这样呢? 因为函数的形参在栈中会被解析成函数的私有变量出现在其执行上下文中,let不允许重复定义。
3.不存在变量提升
只有用var 声明的变量才会有变量提升,let 和const 都不用考虑
4.脱离顶层作用域
我们知道用 var 声明的变量,可以通过window.变量名的形式使用。但是用let/const声明的变量不会绑定在顶层作用域window或globle中5.暂时性死区 TDZ
TDZ又称暂时性死区,意思是变量在作用域内已经存在,必须在 let / const声明后面使用。
ES6明确规定,如果区块中存在let/const命令,这个区块用这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用的变量,就会报错
TDZ本质:只要一进入当前作用域,所要使用的变量就已经存在,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量
TDZ能够让开发者养成先声明后使用的习惯,让程序更加的稳定 -
以上代码if后面{}形成了块级作用域,由于使用let声明了name,则这个变量就绑定了块区域,在声明之前使用,会报错。
隐秘的死区【注意】
-
这里涉及到null和undefined区别
ES6 规定暂时性死区和let,const语句不出现变量提升,主要是为了减小运行时的错误,防止变量在声明前就使用这个变量。
let的以上特性,为js新增了块级作用域
以前为了防止变量被污染,我们常使用自执行函数(IIFE)来防止变量被污染 ,当let广泛使用时,IIFE将不在必要 -
注意:
块级作用域允许相互嵌套
外层作用域不能访问内层变量
不同层级作用域可以定义同名变量
es6允许在块级作用域下声明函数,在块级作用域外面不可引用
凡是有{}者都有块级作用域
ES6的块级作用域必须有大括号 {} 如果没有{} js引擎认为不存在块级作用域
const
const 声明一个只读的常量,一旦声明,常量值就不可以改变。所以const一旦声明就必须立即初始化。
只声明,不赋值,会报错(注意:var let 只声明不赋值 : undefined)
不能重新赋值const定义的值,但是可以修改const’声明的对象类型。 - const 的作用域与let命令相同,只在声明所在的块级作用域内有效
- const声明的变量也不存在变量提升,同样存在暂时性死区,只能在声明位置的后面使用
- const声明的常量和let一样不可重复声明