var
var 声明变量,被视作在函数级作用域内顶部的位置发生(如果不包含在函数内则为全局作用域内)
1 <script> 2 getValue(); 3 function getValue(){ 4 const a=4; 5 if(a>3){ 6 var val='dxj'; 7 console.log(val); 8 return val; 9 }else{ 10 console.log(val); 11 return val; 12 } 13 } 14 </script>
事实上,JS引擎对代码做了如下调整,变量提升,else也可访问到,但其未初始化和赋值,因此undefined
//js引擎对以上函数做了调整 function getValue(condition){ var val; if(condition){ val='dxj'; console.log(val); return val; }else{ console.log(val); return val; } }
循环中使用var
//error
var funcs=[]; for (var i = 0; i < 10; i++) { funcs.push(function(){ console.log(i); }); } funcs.forEach(function(func){ func();//输出十次 10 })
//处理过后
var funcs=[]; for (var i = 0; i < 10; i++) { funcs.push((function(value){ return function(){ console.log(i); } }(i))); } funcs.forEach(function(func){ func();//输出0,1..9 })
let
语法和 var 完全一致,但是变量的作用域会限制在当前的代码块中,不会发生变量提升
getValue(true); function getValue(condition){ if(condition){ let val='dxj'; console.log(val); return val; }else{ console.log(val); return val; } }
注意:
若一个标识符在当前作用域里已经存在,那么再用 let 声明相同的标识符或抛出错误
![](https://img2020.cnblogs.com/i-beta/1794523/202003/1794523-20200314162723839-577043560.png)
![](https://img2020.cnblogs.com/i-beta/1794523/202003/1794523-20200314162741282-1966608304.png)
正常代码如下:
循环中使用let,同样适用于for-in和for-of
1 var funcs=[]; 2 for (let i = 0; i < 10; i++) { 3 funcs.push(function(){ 4 console.log(i); 5 }); 6 } 7 funcs.forEach(function(func){ 8 func();//输出0,1,2..9 9 })
const
声明变量,不会发生变量提升,会被当做常量,不能再次被赋值,因此声明变量要初始化
const count=10; //未初始化 const count;
也不能对已存在的标识符重复定义
var a=7; //语法错误 const a=3; let b=5; //语法错误 const b=7;
const 声明只是阻止变量和值的再次绑定而不是值本身的修改,不能限制对于值的类型为对象的变量的修改
const person={ name:'rt'; }' person.name='yu';
循环中使用const(以下示例会报错),同样适用于for-in和for-of(不会报错)
var funcs=[]; for (const i = 0; i < 10; i++) { //会报错 funcs.push(function(){ console.log(i); }); } funcs.forEach(function(func){ func(); })