JS变量声明提升

Posted smy225

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS变量声明提升相关的知识,希望对你有一定的参考价值。

一、作用域

   JS中,作用域为function内的区域,称为函数作用域。

二、变量声明

  在ES6之前,通过var声明一个变量,但是ES6之后,又添了两个关键词来声明变量:let和const

  var:声明了一个变量,这个变量的作用域是当前执行的上下文

  let:声明了一个块级域的局部变量,并且它声明的变量只在所在的代码块内有效

  const:声明了一个只读的块级域的常量,并且它声明的变量只在所在的代码块内有效

 1 { // 代码块
 2   var a = 1;
 3   let b = 2;
 4   const c = 3;
 5   
 6   console.log(a);   // 1
 7   console.log(b);   // 2
 8   console.log(c);   // 3
 9 }
10 
11 console.log(a);   // 1
12 console.log(b);   // 报错,ReferenceError: b is not defined(…)
13 console.log(c);   // 未执行, 因为上面语句出错,所以这条语句不再执行,如果上面的语句不报错,那么这里就会报错
 1 (function (){
 2   var a = 1;
 3   let b = 2;
 4   const c = 3;
 5   
 6   console.log(a);   // 1
 7   console.log(b);   // 2
 8   console.log(c);   // 3
 9 })();   // 为了方便,这里使用了自执行函数
10 
11 console.log(a);   // 报错,ReferenceError: a is not defined(…)
12 console.log(b);   // 未执行
13 console.log(c);   // 未执行

  let和const不像var那样,会发生变量提升现象

1 console.log(a);    // 报错,ReferenceError: a is not defined
2 let a = 2;
3 console.log(a);    // 待执行

ES6明确规定,如果区块中存在let和const命令,这个区块对这些命令声明的变量,从一开始就形成了封闭作用域。凡是在声明之前就使用这些变量,就会报错。

 

三、变量声明提升

JS在执行前会对整个脚本文件的声明部分做完整解析(包括局部变量),从而确定变量的作用域。

  当局部变量与全局变量重名时,局部变量的范围会覆盖全局变量的范围。当离开局部变量的范围后,又回到全局变量的范围。

 1             var a=1;
 2             function test(){
 3                 alert(a);  //undefined  此处a并不是全局变量,函数里面已经声明了一个重名的局部变量,所以全局变量会被覆盖,JS执行前会对声明部分解析,所以此处的a只是声明但未赋值
 4                 a=4;       //此处a被赋值
 5                 alert(a);  //4 ,此处a仍是局部变量
 6                 var a;     //局部变量a在这里声明
 7                 alert(a);  //4  
 8             }
 9             test();
10             alert(a);      //1,此处a为全局变量
1     var a=10;
2         function test(){
3             a=100;
4             alert(a);        //100  此处a为局部变量,如果没有第三行a=100,此处则为undefined,有了第三行,此处局部变量被赋值为100
5             alert(this.a);   //10   函数内部的this指向的是函数调用者,在这里函数是被全局对象调用,所以此处的this指向全局对象(这里指window)
6             var a;
7             alert(a);        //100   /局部变量100
8         }
9         test()

 

在基本的语句(或者说代码块)中(比如:if语句for语句while语句switch语句for...in语句等),不存在变量声明提升

 

四、函数声明提升

函数声明和函数表达式在语法上是等价的,但有一点不同,函数声明会被提到作用域顶部,而函数表达式不会。

 1 fun();       // hello 
 2 
 3 function fun(){
 4   console.log("hello");
 5 }
 6 
 7 // --------------
 8 // 提升后
 9 
10 function fun(){
11   console.log("hello");
12 }
13 
14 fun();       // hello 
 1 fun();       // 报错,TypeError: fun is not a function
 2 
 3 var fun = function(){
 4   console.log("hello");
 5 };
 6 
 7 // --------------
 8 // 提升后
 9 
10 var fun;
11 
12 fun();        // 报错,TypeError: fun is not a function
13 
14 fun = function(){
15   console.log("hello");
16 };

 

以上是关于JS变量声明提升的主要内容,如果未能解决你的问题,请参考以下文章

JS变量声明提升

JS-作用域

浅谈JS变量声明和函数声明提升

JS执行顺序-函数声明提升匿名函数函数表达式

js变量提升

js变量提升与函数提升