1.let关键字
var arr = [ ]; for(var i=0; i<10; i++){ arr [i] = function(){ alert(i) } } arr [8](); //结果:10
看代码,不难猜测代码的意图是想给数组a的元素赋值,每一个元素是一个函数,运行后弹出相对应的数字,比如:运行arr[8]();想alert出一个数字8,运行arr[1](); 想alert出一个数字1,依次类推。但是结果并不是我们预想的那样。运行后实际弹出的是10;不管你运行的是arr[8]还是arr[5],或者是数组内的其他元素,都是alert出一个数字:10。但这并不是我们想要的,为什么会是10呢?这主要是因为‘变量提升’。
那什么又是变量提升呢?看看下面代码你就明白了
var a = 1; (function(){ alert(a); var a = 2; })();//结果:undefined
//相当于
var a = 1;
(function(){
var a;
alert(a);
var a = 2; })();//结果:undefined
var arr = [ ]; for(let i=0; i<10; i++){ arr[i] = function(){ alert(i) } } arr[8](); //结果:8
为什么用let就可以,用var就跑偏了呢?这是因为let声明的变量仅仅在自己的块级作用域起作用,出了这个块级作用域就不起作用。
如果你用let这样重写刚刚那段代码的话:
var a = 1; (function(){ alert(a); let a = 2; })(); // 结果:报错a未定义
用let关键字来定义a;这样a在代码块内就不会提升了。那为什么又报错了呢,因为用let声明的变量,在其块级作用域内是封闭的,是不会受到外面的全局变量a影响的,并且要先声明再使用,所以a的值即不是1(因为不受外面的影响),也不是undefined(因为先声明后使用),更不是2,未声明定义就使用,只有报错啦。
用let关键字也算是提醒我们,平时记得先声明定义再使用的好习惯
使用let应该注意:
注意1:同一个块级作用域内,不允许重复声明同一个变量。
{ var a =1; let a =2; //报错,因为a已经用var声明过 }
{ let a =1; let a= 2; //还是报错,a已经用let声明过。 }
注意2:函数内不能用let重新声明函数的参数
function say(word){ let word = 'hello Jack'; //报错:用let重新声明word参数 alert(word) } say('hello Lili'); //say()函数内用let重新声明了word这个参数,会报错的,千万别这么干
总结:用let声明变量只在块级作用域起作用,适合在for循环使用,也不会出现变量提升现象。同一个代码块内,不可重复声明的相同变量,不可重复声明函数内的参数。