一 什么是?

概括:
简单说就是在js代码执行前引擎会先进行预编译,预编译期间会将变量声明与函数声明提升至其对应作用域的最顶端。
  1. 变量提升:
    全局作用域中声明的变量会提升至全局最顶层,函数内声明的变量只会提升至该函数作用域最顶层。

    function variableUp() {
     if (!foo) {
         var foo = 5;
     }
    
     console.log(foo); // 5
    }
    
    variableUp();
  2. 函数提升:
    函数提升只会提升函数声明,而不会提升函数表达式,定义形参就相当于在函数作用域中声明了变量

    function funUp(a) {
        conosle.log(a)//output: undefined
        function foo() {
            console.log(1);
        }
    
        foo(); // output: 2
    
        function foo() {
            console.log(2);
        }
    }
    funUp()
    
    var funUp=function(){
      console.log(funUp)
    }

    在JavaScript中的函数是一等公民,函数声明的优先级最高,会被提升至当前作用域最顶端


二 对于变量提升及函数提升的理解

image.png

三 实践例题
题目:

    function fn(a,c){
          console.log(a) //output: function a(){}
          var a=123
          console.log(a)  //output: 123
          console.log(c)  //output: function c(){}
          function a(){}
          if(false){
            var d =678
          }
          console.log(d)  //output: undefined
          console.log(b)  //output: undefined
          var b = function(){}
          console.log(b)   //output: function
          function c(){}
          console.log(c)   //output: function c
      }
      fn(1,2)

分析:

oa={
    a:undefined,//1, function,   123
    c:undefined,//2, function
    d:undefined,
    b:undefined,                //function
}

js中无论哪种形式声明(var, let, const, function, function, class)都会存在提升现象,不同的是,(var,function,function)的声明会在提升时进行初始化赋值为 undefined,因此访问这些变量的时候,不会报 ReferenceError异常,
使用 let,const,class 声明的变量,
被提升后不会被初始化,此时如果访问这些变量会抛出ReferenceError 异常,看上去就像没被提升一样

结束语:无论是早期的代码,还是ES6中的代码,我们都需要遵循一点,先声明,后使用。


LYIN
39 声望5 粉丝

WEB前端