一、 关键字 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');