let和var的使用范围和关于变量提升的定义

611 阅读2分钟

每一个js程序执行的时候会分为编译阶段和执行阶段(赋值语句是属于执行阶段):编译阶段就是把js变量的声明提升到当前作用域的最前端,就会生成一个scope域,把所有声明的的变量放入scope。当执行代码时,就会到scope里寻找所需要的变量。var声明变量会变量提升到作用域的最前端生成var 变量=undefined。

来:我们一起看看下图表结论

关键字变量提升块级作用域重复声明同名变量重新赋值
var
let

变量提升:

变量提升:
/*用var声明变量*/
    console.log(num);   //输出undefined
    var num=10;
    //上面代码运行时相当于下面的写法
    /************************************/
    //编译过程变量提升后的代码
    var num=undefined   //声明到作用域顶端
    //执行过程代码
    num=10        
    consosole.log(num)   //输出undefined
    
    /*用let声明变量*/
    console.log(b);   //报错 b is not defined
    console.log(num1);  //报错 Cannot access 'num1' before initialization初始化前无法访问
    let num1=10;
    /*

从let声明变量来看,let是存在变量提升的,但是不能被初始化。如果没有,那我们的log(x)的报错是与log(num1)的报错是一样的,但是var的变量提升的空间对象与let的空间对象并不并存在一起,let放在临时暂死区。 那什么叫临时暂时区,let声明的变量提升是存在的,但是不让用。变量提升其实是一个bug,let的产生就是用来修补变量提升bug的方案,变量提升是js的运行机制。

块级作用域:ps:一对{}就是一个块级作用域

{
var a=‘hello'
}
cosole.log(a);  //能正确输出hello

for(var i=0;i<5;i++){
}console.log(i)//输出5

let a='hello'
}
cosole.log(a)//ReferenceError: a is not defined

for(let i=0;i<5;i++){
}console.log(i)//ReferenceError: i is not defined

var是不存在块级作用域的,let是存在块级作用域的

重复声明同名变量:

//var可以声明同名变量,实际第二次声明是对第一次声明的重新赋值
var a=10;
var a=100;
console.log(a);//100
 //let不能重复声明同名变量,即使之前使用var也会报错
 let a=10;
 let a=100;
 console.log(a)//Identifier 'a' has already been declared
 
 var a=10;
 let a=20;
console.log(a);//SyntaxError: Identifier 'a' has already been declared
//var和let的作用域不一样是可以同时声明
var a=10;
{
let a=100;
}
console.log(a);//10

重新赋值:

//let 声明变量可以重新赋值,var也可以
let a=10;
a=20;
console.log(a)//20