一、let定义的变量不会变量提升,var有变量提升机制
我们直接看实例
console.log(num);//=>undefined
var num = 20; //=>定义一个变量
console.log(num);//=>20
我们将代码中的var修改为let
console.log(num);//=>Uncaught ReferenceError: Cannot access 'num' before initialization
let num = 20; //=>定义一个变量
console.log(num);
我们可以看见区别:
当我们使用的是var定义变量的时候,我们在定义之前输出会输出undefined,但是在使用let定义变量的时候,会报错(报错的意思大概是说我们不能在变量初始化前使用),所以我们可以得知let定义的变量没有变量提升机制。还可以知道let声明的变量不能再声明前使用。
二、let定义的变量不能重复声明
//我们同时定义(声明)了两次变量num,输出的结果是我们第二次定义的20
var num = 10;
var num = 20;
console.log(num); //=>20
//同样的代码我们只是将var改成let
//代码执行在第二行的时候报错(num变量重复定义)
let num = 10;
let num = 20;//Uncaught SyntaxError: Identifier 'num' has already been declared
console.log(num);
三、let会形成块级作用域
{
let i = 10;
}
console.log(i);//Uncaught ReferenceError: i is not defined
//因为let有块级作用域,所以只能在声明i的作用域使用
{
var i = 10;
}
console.log(i);//=> 10
//var没有块级作用域所以可以得到结果
用一个案例体会一下let的好处
需求:有4个LI当我们点击每个LI的时候在控制台输出对应的索引
HTML代码
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
ul {
list-style: none;
}
li {
margin-top: 20px;
height: 30px;
width: 100px;
background: red;
}
</style>
</head>
<body>
<ul class="list">
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</body>
</html>
Javascript (var)
var list = document.querySelectorAll('.list>li');
for (var i = 0; i < list.length; i++) {
list[i].onclick = function () {
console.log(i);
}
}
Javascript (let)
//将for循环中的var修改为了let
var list = document.querySelectorAll('.list>li');
for (let i = 0; i < list.length; i++) {
list[i].onclick = function () {
console.log(i);
}
}
只将for循环中声明变量的方式改为了let,结果却截然不同。
原因就是:JS中的for循环体比较特殊,每次执行都是一个全新的独立的块作用域,用let声明的变量传入到 for循环体的作用域后,不会发生改变,不受外界的影响。
四、let会产生暂时性死区
var num = 10;
if(true){
console.log(num);//Uncaught ReferenceError: Cannot access 'num' before initialization
let num;
}
代码中,声明了一个全局变量num,然后我们在if中打印num,按理说我们是可以打印出num这个变量的值,但是运行时报错。这是因为let的暂时性死区所导致的。
只要块级作用域内存在 let 命令,它所声明的变量就绑定这个块级域,不再受外部的影响。代码中又在if域中定义了num,所以num这个变量绑定在该块作用域,我们在变量还没定义的时候就使用,自然就会报错。
总结
1.let定以的变量会形成块级作用域,可以用于循环绑定事件
2.let不能在未声明前使用,否则会报错
创作不易,有什么错误,请大家在评论区指出。