什么是ES6语法?
我们现在惯称的ES6即ECMACScript6.0,也叫ES2015。
变量声明-var, let, const三者的区别
ES6提供了新的声明方式替代了以前的var。取而代之的是let和const。
var的特点:
使用var声明,在同一个作用域下可以多次声明同一个变量。
var a = 1;
function fn (){
var a = 2;
var a = 3;
return a;
}
var a = fn();
console.log(a); // 在这里a一共被声明了4次
用var声明会使变量声明到window全局作用域上,var不支持封闭作用域,在for循环中声明的变量在for循环外也能拿到 (作用与污染)。
for(var i = 0; i < 10; i++){
console.log(i);
}
console.log(i);
console.log(window.i);
作用域分为函数作用域和全局作用域,以往为了不将for循环中的变量声明到全局上我们的做法是在for循环外套一个闭包(即自调用函数)。
(function(){
for(var i = 0; i < 10; i++){
console.log(i);
}
})();
console.log(i);
console.log(window.i);
但当我们需要在for循环里写一些异步代码的时候用以上方法写出来的代码会较为复杂不利于后期更新维护。例如我们在for循环里写一个延时器setTimeout(),setTimeout()是一个异步函数。
for( var i = 0; i < 10; i++){
setTimeout(function(){
console.log(i);
},1000)
}
因为代码的执行顺序是先执行同步代码,把异步代码先压到一个队列里去等待同步代码执行完后再开始清空队列。在同步代码都执行完以后上面for循环里的i已经变成了全局的10,这时候再用setTimeout()打印就只能打印出10个10。
用以上的方法就是把异步函数setTimeout()放进闭包里使它可以获取到每次循环的i。
for(var i = 0; i < 10; i++){
(function(i){
setTimeout(function(){
console.log(i);
},1000)
})(i);
}
let的特点:
同样实现以上的功能,我们改用let声明可以大大简化代码。
let和{}配合可以产生一个作用域。
let支持块级作用域。声明的变量只会声明在当前作用域内。
let可以解决作用域污染问题和局部作用域问题。
for(let i = 0; i < 10; i++){
setTimeout(function(){
console.log(i);
},1000)
}
let声明同一个作用域内同一个变量只能被声明一次。
function fn (){
let a = 1;
let a = 2;
}
fn(); // 报错-Identifier 'a' has already been declared
【注意】同一个作用域内若用let声明过了就不要再用var了
let与预解析问题
当用var声明变量时,由于js的预解析机制,声明会被提升到当前作用域最前面。
当用let声明时,预解析问题不会产生。也就是说用let声明可以解决变量提升的问题。
暂存死区
在一条作用域链中,当用let在外部作用域声明一个变量并在局部作用域打印后再重新声明时,由于用let没有变量提升,但打印时程序也没有向外部作用域获取变量,此时的局部作用域被称为暂存死区。
如果在一个局部作用域内用let声明一个变量,该局部作用域就会绑定这个变量,在这个作用域内执行的程序无论在变量之前还是之后都不会再向上查找其他变量,这就是暂存死区的原理。
【注意】当局部作用域没有绑定变量时,向上查找机制如常。
const的特点:
通过const声明的变量不能被修改。
这里的修改指的是修改引用空间和变量地址。