在ES6之前我们声明变量、函数等是用var关键字,ES6新增了let 和 const 供我们声明变量、函数等。
那它们具体有什么区别呢?
- var声明的变量会声明提升,let 和 const 声明的变量不会。
- 在循环中,用var声明的变量里存储的值会跟随循环的变化而变化,总之最后var变量里的值是最后一次执行操作的值;而let和const声明的变量,每次循环都会定义一个互不干扰的新变量,相当于多少次循环就有多少个独立变量,里面存储的值互不干扰。
- 用var定义的变量可以用var关键字重新声明赋值,let和const不行。
- var定义变量,除了全局作用域,一个函数相当于一个独立作用域;let和const是一对{}相当于一个作用域;
- var一般用于定义基本数据类型,const用于定义常量和复杂数据类型,const定义常量时不能重复赋值;
图解:
1、声明提升,也就是如果在var语句之前调用输出var声明的变量,该变量的值是undefined;而在let声明变量之前调用会报错。
<script>
console.log(a); //控制台中输入undefined
var a = 1;
</script>
<script>
console.log(a); //控制台报错
let a = 1;
</script>
2、var定义变量时,一个函数相当于一个作用域;let 定义变量时,一个{}相当于一个作用域;
<script>
var a = 1;
if (true) {
var a = 5;
console.log(a); //控制台输出5
}
function fun() {
var a = 2;
console.log(a); //控制台输出2
}
fun();
console.log(a); //控制台输出5
</script>
<script>
let a = 1;
if (true) {
let a = 5;
console.log(a); //控制台输出5
}
function fun() {
let a = 2;
console.log(a); //控制台输出2
}
fun();
console.log(a); //控制台输出1
</script>
3、在同一个作用域内可以重复使用var关键字定义赋值,后面定义的会覆盖前面的值。同一个作用域内let关键字不可以重复定义赋值,会报错;
<script>
var a = 1;
var a = 3;
function fun() {
var b = 2;
var b = 4;
console.log(a); //控制台中输入3
console.log(b); //控制台中输入4
}
fun();
</script>
<script>
let a = 1;
let a = 3;
function fun() {
let b = 2;
let b = 4;
console.log(a); //控制台报错,后面的程序不执行
console.log(b);
}
fun();
</script>
4、循环中,var定义的变量里存储的是最后一次操作的值,let定义的变量会根据每次循环建立一个新的互不干扰的独立变量。
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<script>
var oUllis = document.querySelectorAll('ul li');
for (var i = 0; i < 4; i++) {
oUllis[i].addEventListener('click', function() {
console.log(i + 1); //不管点谁,控制台中都输出5
});
}
</script>
</body>
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<script>
var oUllis = document.querySelectorAll('ul li');
for (let i = 0; i < 4; i++) {
oUllis[i].addEventListener('click', function() {
console.log(i + 1); //控制台输出与列表内容对应的值
});
}
</script>
</body>