1. let关键字就是用来声明变量的

2. 使用let关键字声明的变量具有块级作用域

3. 在一个大括号内,使用let关键字声明的变量才具有块级作用域,var关键字是不具备这个特点的

4. 防止循环变量变为全局变量

5. 使用let关键字声明的变量没有变量提升

6. 使用let关键字声明的变量具有暂时性死区特性

1.let关键字声明变量

  1. let a = 10;
  2. console.log(a);//10

2.使用let关键字声明的变量具有块级作用域

  1. if (true) {
  2. let b = 20;
  3. console.log(b); //20
  4. }
  5. console.log(b); //报错

3.-在一个大括号中 使用let关键字声明的变量才具有块级作用域 var关键字是不具备这个特点的

  1. if (true) {
  2. let num = 100;
  3. var abc = 200;
  4. }
  5. console.log(abc); //200
  6. console.log(num); //报错

4.防止循环变量标为全局变量

(1)var关键字在循环中

  1. for (var i = 0; i < 2; i++) {}
  2. console.log(i);//2

循环已经结束了,这时里面的变量应该销毁才对,可是却在es6以前var关键字中成为了全局变量
(2)let关键字在循环中

  1. for (let i = 0; i < 2; i++) {}
  2. console.log(i); //报错

5.使用let关键字声明的变量没有变量提升

  1. console.log(a);
  2. let a = 20; //报错

6.使用let关键字声明的变量具有暂时性死区特性

  1. var num = 10;
  2. if (true) {
  3. console.log(num);
  4. let num = 20; //报错
  5. }

由于有了let关键字的存在这个块级作用域 已经被let所特定,与上面的var声明的没有关系

经典面试题

1.首先我们看一个使用var关键字的循环

  1. var arr = [];
  2. for (var i = 0; i < 2; i++) {
  3. arr[i] = function() {
  4. console.log(i);
  5. }
  6. }
  7. arr[0]();//2
  8. arr[1]();//2

这里输出的都是2,安静在此简要阐述一下,通过打断点的方式我们发现代码从上至下一次执行,当 i =0,传输给 i <2满足条件时直接跑到下面执行括号内的,由于是函数,因为函数没有被调用使用不执行,继续执行循环,以此类推当i等于一时,也是不执行函数,最后因为 i=2不满足循环体了,所以退出循环,接着执行调用函数的代码,记住此时 i = 2;然后我们发现 输出的值明显为2
image.png通过这张图让我们理解的更深刻
2.接下来我们把关键字 var 换成 let

  1. let arr = [];
  2. for (let i = 0; i < 2; i++) {
  3. arr[i] = function() {
  4. console.log(i);
  5. }
  6. }
  7. arr[0](); //0
  8. arr[1](); //1

我们通过打断点发现执行的流程没有变化,变化在于:
此题关键点在于每次循环都会产生一个块级作用域,每个块级作用域中的变量都是不同的,函数执行时输出的是自己上一级(循环的块级作用域)作用域下的值,
image.png
image.png