var 声明提升:在函数内部,变量也会提升到函数顶部。但变量的赋值还是处于声明的位置。
块级声明
块级作用域:也叫词法作用域,存在于:
- 函数作用域中
- {}中
let
- 没有声明提升,所以通常写在块级作用域顶部。
- 禁止重申明
const
- 没有声明提升
- 禁止重申明
- 声明的是常量,不能更改。
- 如果是对象,则不能更改指针的绑定,但能修改对象中的属性。
临时死区(TDZ)
let和const的变量在引擎发现声明时,会发到临时死区中。访问临时死区的变量会触发错误,此时在该块级作用域中使用typeof也会报错。只有执行完声明语句后,才会从临时死区中移除,正常访问。
for(let i=0;i<10;i++){ console.log(typeof xiao) let xiao=2;} //报错循环中的块级作用域绑定
for循环的()中,声明的let只属于这个循环。并且每次迭代都会创建一个新绑定,并以之前迭代中同名变量的值初始化。
var funs=[];for(let i=0;i<10;i++){ funs.push(function (){ console.log(i); })}funs.forEach(function(func){ func();}) //0,1,2……9这个是es6特意针对循环设置的规则。
此规则对for-in等循环均有效。
const在循环中与let是一样的,因为每次循环不是赋值,而是创建新绑定。只是for循环中的i++会导致错误,因为试图更改i的值。
全局块作用域绑定
在全局中使用let和const与var不太一样。var会覆盖已有的全局变量,如Object。而let和const只是屏蔽,且创建的变量不是window的属性,使用window.Object时,依然可以访问原生Object。
块级绑定的最佳实践
一般用const。遇到实在要改变的变量才有let。var不太常用。