一、 关键字 let
 正如大家都熟悉的,我们平时在写代码的时候,用var 声明一个变量,除此之外,也再没有接触到其它的关键字了,不管我们声明什么样类型得变量,都用var 搞定了,很方便,但是ES6 告诉你,除了var,还可以试试 let 来声明变量。
 那么,既然var 方便,为什么还要let 来声明,这么说 var 声明 一定会有不足的地方。
 下面介绍 用 var 的不足之处。
 1.先看一段代码
 var arr = [ ]; for(var i=0;  i<10;  i++){     arr [i] = function(){          alert(i)     } } arr [1](); //结果:10 
 很明显,我们执行这段代码的想要的结果是弹出arr 这个数组对应索引的值。但发现无论索引是几 弹出结果都是10。
 Why ?
 继续执行这段代码看看:
 var arr = [ ]; for(let i=0;  i<10;  i++){     arr[i] = function(){          alert(i)     } } arr[1](); //结果:1  
 居然弹出了对应索引的值!对比一下两段代码,唯一的不同之处就是循环的时候初始化变量 i 是使用let,而不是用var, Why ? ?
 原来,let声明的变量仅仅在自己使用的块级作用域起作用,出了这个块级作用域就不起作用了。
 注意:块级作用域 即任何一对花括号中的语句都属于一个快,在花括号用let 定义的所有变量在花括号外都是不可见的,我们称之为 块级作用域。
 那么回到代码中,for循环含有{ },也就是含有了块级作用域,每个变量 i 都只是在自己的作用域起作用,例如:第10次循环中的 i 的值不会影响到到第9次循环。
 ok!
 2.var 声明变量会出现“变量提升“。
 What ?
 上代码:
 var a = 1; (function(){    alert(a);    var a = 2; })();//结果:undefined 
 猛的一看,结果不应该是 1 吗,为什么会是未定义呢?
 原因就在于我们在代码块(函数内)里面还声明并定义了一个变量a,导致变量提升了,实际的代码执行顺序是这样的,认真看完你就明白道什么叫变量提升了。
 var a = 1; (function(){    var a;    alert(a);    a = 2; })(); 
 对比一下两段代码:var a = 2; 这句代码被拆分成两部分:声明var a ; 和 定义a = 2;而声明部分被提升了,到了代码块的前面,运行的时候自己挪到前面了,这就是“变量提升“,结果就是:先执行声明,接着就执行alert(a);变量a只是声明还没定义,就弹出了undefined了。
 那么,用let关键字在代码块就不会被提升了吗? 确定以及肯定。
 var a = 1; (function(){    alert(a);    let a = 2; })();   // 结果:报错a未定义 
 那为什么又报错了呢,因为用let声明的变量,在其块级作用域内是封闭的,是不会受到外面的全局变量a影响的,并且要先声明再使用,所以a的值即不是1(因为不受外面的影响),也不是undefined(因为先声明后使用),更不是2,未声明定义就使用,那只有报错了。
 注意:let关键字要记得先声明定义再使用。
 3.使用let 其它注意点
 (1) 同一个块级作用域内,不允许重复声明同一个变量。
 错误实例:
 {   var a =1;   let a =2;   //报错,因为a已经用var声明过 } 
 {   let a =1;   let a= 2;  // 还是报错,a已经用let声明过。 } 
 (2) 函数内不能用let重新声明函数的参数
 function say(name){     let name = 'zhang';  //报错:用let重新声明name参数    alert(name) } say('wang'); 
 say()函数内用let重新声明了name这个参数,No!
 小结:
 用 let 声明变量只在块级作用域起作用,适合在 for 循环使用,也不会出现变量提升现象。同一个代码块内,不可重复声明的相同变量,不可重复声明函数内的参数。
 后续更新...