var 、let、const的区别
var | let | const |
---|---|---|
函数级作用域 | 块级作用域 | 块级作用域 |
变量提升 | 不存在变量提升 | 不存在变量提升 |
值可更改 | 值可更改 | 值不可更改 |
1. var
-
只有var关键字才有变量提升
-
变量提升到当前作用域最前面
-
只提升变量声明,不提升变量赋值
console.log(num);//undefined var num = 10;
-
经典面试题
var arr = []; for(var i=0;i<2;i++){ var全局变量 console.log(i)//0 1 arr[i] = function() { //循环时并没有执行这个方法 console.log(i)//2 } } console.log(i)//2 当i=2时循环结束,接着往下执行代码,此时function还没调用 //执行到这,循环已经结束了,方法本身没有i,根据作用域链查找原则,向上一层找到i,此时的i为全局变量i,值为2 arr[0]();//2 arr[0]是一个function,执行输出的i是全局变量i,此时i为2 arr[1]();//2 var arr = []; for(let i=0;i<2;i++){ let块级作用域,i=0为一个作用域,i=1为一个作用域 arr[i] = function() { console.log(i) //所以 i 向上一级作用域查找 } } console.log(i)//let块级作用域 i is not defined arr[0]();//0 向i=0的作用域查找 arr[1]();//1 向i=1的作用域查找
2. let
-
let关键字没有变量提升
console.log(num);//num is not defined let num = 10; var num = 10; if(true) { console.log(num);//报错 let num = 20;//声明变量,则形成块级作用域,与{}外定义的全局num没有关系 }
-
在大括号 {} 中使用 let 关键字声明变量才具有块级作用域,var不具备
if(true){ let num = 100; var abc = 200; } console.log(abc);//200 console.log(num);//num is not defined
-
防止循环变量变成全局变量
for(let i= 0; i<2; i++){ } console.log(i);//i is not defined 用var可以访问到为2
3.const 声明常量
-
具有块级作用域
if(true){ const a = 10; if(true) { const a = 20; console.log(a);//20 } console.log(a);//10 } console.log(a);//a is not defined
-
声明的常量必须赋初始值
const a; //Missing initializer in const declaration
-
常量声明后值不可更改
1. 基本数据类型,值不可更改 const a = 1; a = 2;//Assignment to constant variable. 2. 复杂数据类型,数据结构内部的值可以更改,数据值本身不可更改(也就是说常量值对应的内存地址不可改) const arr = [100,200]; arr[0] = 1; //arr = [1,200]; arr = [1,2];//Assignment to constant variable.