前端基础知识:javascript变量提升

Javascript中,函数及变量的声明都将被提升到函数的最顶部,提升的仅仅是变量的声明,变量的赋值并不会被提升。我们需要注意的是,函数的声明与变量的声明是不一样的。函数的函数体也会被一起提升。
函数表达式和变量表达式只是其声明被提升,函数声明是函数的声明和实现都被提升。

function foo() {  
  console.log("global foo");  
}  

function bar() {  
   console.log("global bar");  
}  

//定义全局变量  
var v = "global var";  

function hoistMe() {
   // var bar; 被提升到顶部,并未实现
   // var v;
   console.log(typeof foo); //function  
   console.log(typeof bar); //undefined  
   console.log(v); //undefined  
  
   // 函数里面定义了同名的函数和变量,无论在函数的任何位置定义这些函数和和变量,它们都将被提升到函数的最顶部。  

   foo(); //local foo  
   bar(); //报错,TypeError "bar is not a function"

    //函数声明,变量foo以及其实现被提升到hoistMe函数顶部  
   function foo() {  
     alert("local foo");  
   }  

   //函数表达式,仅变量bar被提升到函数顶部,实现没有被提升  
   var bar = function() {  
       alert("local bar");  
   };  

   //定义局部变量  
   var v = "local";  
}  

let 变量提升

console.log(a); // Uncaught ReferenceError: a is not defined
let a = "I am a";

let b = "I am outside B";
if(true){
    console.log(b); // Uncaught ReferenceError: b is not defined
    let b = " I am inside B";
}

如果b没有变量提升,执行到console.log时应该是输出全局作用域中的b,而不是出现错误。

我们可以推知,这里确实出现了变量提升,而我们不能够访问的原因事实上是因为let的死区设计:当前作用域顶部到该变量声明位置中间的部分,都是该let变量的死区,在死区中,禁止访问该变量。由此,我们给出结论,let声明的变量存在变量提升, 但是由于死区我们无法在声明前访问这个变量。

THE END