es6 新增 let 与 var 比较
用var的不足之处
不足一
var arr = [ ];
for(var i=0; i<10; i++){
arr [i] = function(){
alert(i)
}
}
arr [8](); //结果:10
看代码,不难猜测代码的意图是想给数组a的元素赋值,每一个元素是一个函数,运行后弹出相对应的数字,比如:运行arr8;想alert出一个数字8,运行arr1; 想alert出一个数字1,依次类推。但是结果并不是我们预想的那样。运行后实际弹出的是10;不管你运行的是arr[8]还是arr[5],或者是数组内的其他元素,都是alert出一个数字:10。但这并不是我们想要的(不要说你故意这么写的,就是想弹出10就好了),为什么是10呢(往下读,有解释)?至少目前我们可以知道了这是var不足的地方。
用let替换var之后 完美解决块级作用域问题
var arr = [ ];
for(let i=0; i<10; i++){
arr[i] = function(){
alert(i)
}
}
arr[8](); //结果:8
这是因为let声明的变量仅仅在自己的块级作用域起作用,出了这个块级作用域就不起作用。
任何一对花括号 { } 中的语句都属于一个块,在花括号里面用let定义的所有变量在花括号外都是不可见的,我们称之为块级作用域。
不足二
用var 声明变量的时候会出现“变量提升“的现象。
var a = 1;
(function(){
alert(a);
var a = 2;
})();//结果:undefined
实际执行顺序如下
var a = 1;
(function(){
var a;
alert(a);
a = 2;
})();
用let关键字来定义a;这样a在代码块内就不会提升了。那为什么又报错了呢,因为用let声明的变量,在其块级作用域内是封闭的,是不会受到外面的全局变量a影响的,并且要先声明再使用,所以a的值即不是1(因为不受外面的影响),也不是undefined(因为先声明后使用),更不是2,未声明定义就使用,只有报错啦。
var a = 1;
(function(){
alert(a);
let a = 2;
})(); // 结果:报错a未定义
使用let 需要注意
*在同一块级作用域下,不允许重复声明同一个变量
{
var a =1;
let a =2; //报错,因为a已经用var声明过
}
{
let a =1;
let a= 2; //还是报错,a已经用let声明过。
}
*函数内不能用let重新声明函数的参数
function say(word){
let word = 'hello Jack'; //报错:用let重新声明word参数
alert(word)
}
say('hello Lili');
总结:用let声明变量只在块级作用域起作用,适合在for循环使用,也不会出现变量提升现象。同一个代码块内,不可重复声明的相同变量,不可重复声明函数内的参数。
es6也给我们提供了另一个关键字constconst是constant(常量)的缩写,const和 let一样,也是用来声明变量的,但是const是专门用于声明一个常量的,顾名思义,常量的值是不可改变的。以前用var声明的变量,想怎么改就怎么改,同一个变量,后面的值可以轻松覆盖原来的值,这次const声明的变量,可由不得我们这么任性地想改就改了。
const有以下几个特点
1.不可修改
2.只有块级作用域起作用
3.不存在变量提示,必须先声明后使用
4.不可重复声明同一个变量
5.声明后必须赋值
常量还可以是一个对象,这里在赋值过程中,我们可以分为传值赋值和传址赋值。
传址:在赋值过程中,变量实际上存储的是数据的地址(对数据的引用),而不是原始数据或者数据的拷贝。
用const来声明一个对象类型的常量,就是传址赋值。而不可修改的是对象在内存中的地址.我们修改的都是对象身上的属性,所以并没有违背常量不可修改的约定。
总结:const也是用于声明一个常量,并必须赋值,声明后不可修改,跟let一样,只在块级作用域起作用,不可重复声明同一个变量,不会变量提升,声明引用类型的常量时,要注意是传址赋值。