var异步
若是使用关键字 var 声明一个变量,那么这个变量就属于当前的函数做用域,若是声明是发生在任何函数外的顶层声明,那么这个变量就属于全局做用域。函数
let
一、let 声明的变量具备块做用域的特征。
二、在同一个块级做用域,不能重复声明变量。
function foo(){
let a = 1;
let a = 2;//Uncaught SyntaxError: Identifier 'a' has already been declared
}spa
三、let 声明的变量不存在变量提高,换一种说法,就是 let 声明存在暂时性死区(TDZ)。线程
for (var i = 0; i < 5; i++) {
setTimeout(function(){
console.log(i);
},100)
};
会打印4个4 :setTimeout是异步执行的,100毫秒后向任务队列里添加一个任务,只有主线上的所有执行完才会执行任务队列里的任务,因此当主线程for循环执行完以后 i 的值为5,这个时候再去任务队列中执行任务,i所有为5;每次for循环的时候setTimeout都会执行,可是里面的function则不会执行被放入任务队列,所以放了5次;for循环的5次执行完以后不到1000毫秒;1000毫秒后所有执行任务队列中的函数,因此就是输出五个5啦生命周期
for (let i = 0; i < 5; i++) {
setTimeout(function(){
console.log(i);
},100)
};
会打印0,1,2,3,4:假如把var换成let,那么输出结果为0,1,2,3,4;由于let i 的是区块变量,每一个i只能存活到大括号结束,并不会把后面的for循环的 i 值赋给前面的setTimeout中的i;而var i 则是局部变量,这个 i 的生命周期不受for循环的大括号限制;队列
const作用域
声明方式,除了具备 let 的上述特色外,其还具有一个特色,即 const 定义的变量,一旦定义后,就不能修改,即 const 声明的为常量。io
const obj = {a:1,b:2};
console.log(obj.a);//1
obj.a = 3;
console.log(obj.a);//3console
因此准确的说,是 const 声明建立一个值的只读引用。但这并不意味着它所持有的值是不可变的,只是变量标识符不能从新分配。for循环