let、var和函数声明,const

170 阅读4分钟

这儿小小梳理一下js变量的声明和提升,提前都知道,js从上向下顺序执行的,除异步代码的执行。写了几个小案例,了解下这几个的变量声明情况。

1、var定义变量

var a ;
console.log(a);    //var声明变量,该变量初始化值为undefined
a = 1;
console.log(a);   // 1
var a;  //同一作用域中,可以有同名的 var 声明的变量
console.log(a); //1  已经有名称为a的var变量,第一次赋值为1,这儿是1
a = 2;
console.log(a);  // 2
function f(){
    console.log(a);
}
f(); // 2  var声明的变量a,最后一次赋值的是2,此处是2
function f1(){
    console.log(a);
    var a;
}
f1();  // undefined 在f1函数体内的作用域中,var声明了变量a,提升到函数的顶部,初始化值为undefined
function f2(){
  console.log(a); //undefined
  var a = 3;
  console.log(a); //3
}
//console.log(b) //不注释该语句,此处报错,以下的不再执行
b = 5; //可以不使用 var,也可以行,但是变量不会声明提升
console.log(b); //5
function a(){}   //函数名函数名和变量名同名时,被变量名覆盖,即使该函数是在最顶部定义的,也是如此
console.log(a); //2 函数名和变量名相同时,变量名高于函数名 
a();  //报错,函数名和变量名同名时,被变量名覆盖,找不到名为a的函数

总结:

var声明的变量,初始化值为undefined;

进行了变量声明提升,提升到当前作用域的最顶部;

相同作用域内允许有同名的变量,程序自顶向下执行,当执行到某位置,该变量的值为程序执行到该位置时最后一次的赋值为该变量在此处的值;

函数体可以隔离不同的作用域,在某一个作用域内,某个位置要访问某个变量,先从该位置向上查找这个变量,第一个查找到的就是该变量,如果在当前作用域中找不到该变量,则向上一作用域中查找该变量,直至找到该变量,最终找不到,则为null;

2、let 声明的变量

//console.log(a); //不注释该语句,此处报错,以下不再执行
let a;
console.log(a); //undefined, let 声明变量,该变量初始化值为undefined
a = 1;
console.log(a); //1
//let a;  //不注释该语句,整个js文件只报错
function f(){
  console.log(a);
}
f(); //1
function f1(){
  console.log(a); //下面let声明的变量没有进行声明提升,此处a变量要向上查找a,找到外层作用域中的a,
                  //再向上,就近一次赋值为1
  let a = 123;
}
f1(); //1

总结:

let 声明的变量,初始化值为undefined,不进行变量声明提升;

同一作用域中不允许有同名的let声明的变量,否则报错,整个js文件报错

let声明的变量,取值的方法同var声明的变量

3、function函数声明

var f;
function f(){
  console.log(1);
}
f = 2;
console.log(f); //2 var声明的变量f和function声明的函数名都提升,在此处之前,f最后赋值为2,取值2
function f(){
  console.log(f);
}
console.log(f); //2 同名的变量名和函数名,函数的声明和赋值先于变量的声明和赋值,
                //在此处f最后一次赋值为2
f(); //f is not a function, f最后一次赋值为2
function f1(){}
function f1(){
  console.log(1)
}
console.log(f1); // function f1(){console.log(1)} 
                 //第二个名为f1的函数声明覆盖了第一个名为f1的函数声明

总结:

函数的声明,是将函数名和函数体同时声明提升;

同名的函数和变量,函数的声明优先于变量的声明;

在某个位置以上,同名的函数,最后一次的函数声明覆盖掉之前的函数声明;

函数名的查找方法同变量的查找方法

4、const声明的变量

const a; //Missing initializer in const declaration 

总结:

const声明的变量,不会进行提升;

const声明的变量,需要随即初始化为一个值,无值时,会报错

全文总结:

上面的梳理涉及到了js的预解析和词法作用域,使用通俗的语言,阐释了对这块儿的理解