函數聲明與函數表達式的區別

函數聲明(funDeclaration)

不管在哪兒定義函數,只要是外層函數而且知足不被包裹,就均可以進行全局範圍的調用javascript

function foo() { }

在函數體內部的函數聲明沒法提高到全局,只能提高到函數體內頂部(塊級做用域空間)html

function test() {
    console.log(1);

    function test2() {
      console.log(2);
    }

  }
  test();  // 1
  test2(); // Uncaught ReferenceError: test2 is not defined

函數體內部執行:java

function test() {
   
    test2();
    function test2() {
      console.log(2);
    }
  }
  test(); // 2

在外部要想訪問函數內部申明的函數,須要先return出來:瀏覽器

function test() {
    console.log(1);

    function test2() {
      console.log(2);
    }
    return {
      test2:test2
    }
  }
  test().test2(); // 2

函數表達式(funExpression)

函數表達式須要等到表達式賦值 完成 才能夠函數

換言之使用 var來聲明函數,就會涉及到變量的聲明提高,先拿出變量名定義爲undefined,再隨着邏輯順序進行賦值 先定義,後使用
var foo = function () { }

demo1

Toast()    // hello world

    showToast(); // shwoToast is not a function

    var showToast = function () {
      console.log('123')
    }
    function Toast() {
      console.log('hello world') 
    }
在這裏只須要把 showToast 提早就行了

demo2

主流瀏覽器解析,ie11+

var sayHello;
    console.log(typeof (sayHey));//=>undefined   
    console.log(typeof (sayHo));//=>undefined
    if (true) {
      function sayHey() {
        console.log("sayHey");
      }
      sayHello = function sayHo() {
        console.log("sayHello");
      }
    } else {
      function sayHey() {
        console.log("sayHey2");
      }
      sayHello = function sayHo() {
        console.log("sayHello2");
      }
    }
    sayHey();// => sayHey   
    sayHello();// => sayHello

在花括號裏面聲明的函數在進行預解析時只會提高函數名,不會提高函數體,因此無論if條件是否爲真,函數體都不會提高,永遠是undefined,接下來隨着if條件判斷進行解析賦值,固然是走ture方法。code

ie9,ie10

var sayHello;
    console.log(typeof (sayHey));//=>function    
    console.log(typeof (sayHo));//=>undefined
    if (true) {
        function sayHey() {
            console.log("sayHey");
        }
        sayHello = function sayHo() {
            console.log("sayHello");
    }
    } else {
        function sayHey() {
            console.log("sayHey2");
        }
        sayHello = function sayHo() {
            console.log("sayHello2");
        }
    }    
    sayHey();// => sayHey2    
    sayHello();// => sayHello

在這裏的ie將全部的函數聲明進行了提高,從而由sayHey2替代了sayHey,函數表達式的在順着條件判斷進行了定義,執行爲true的狀況,進行賦值解析。htm

ie8

var sayHello;
    console.log(typeof (sayHey));//=>function    
    console.log(typeof (sayHello));//=>function
    if (true) {
        function sayHey() {
            console.log("sayHey");
        }
        sayHello = function sayHo() {
            console.log("sayHello");
    }
    } else {
        function sayHey() {
            console.log("sayHey2");
        }
        sayHello = function sayHo() {
            console.log("sayHello2");
        }
    }    
    sayHey();// => sayHey2    
    sayHello();// => sayHello

ie8在這裏處理的比較奇葩,正常的函數申明提高,可是卻也將條件判斷爲假的狀況進行了提高,咱們看到typeof (sayHello)=>functionblog

結論

因爲函數聲明提高的差別,想要在條件判斷中定義不一樣的函數方法,應該採用定義函數表達式的方法,這樣就在各個瀏覽器中拿到相同的函數方法,獲得相同的結果。ip

var sayHello;
    console.log(typeof (sayHey));//=>undefined    ie8如下解析爲function
    console.log(typeof (sayHo));//=>undefined
    if (true) {
      var sayHey =function sayHey() {
        console.log("sayHey");
      }
     
    } else {
      var sayHey =function sayHey() {
        console.log("sayHey2");
      }
     
    }
    sayHey();// => sayHey
參考
相關文章
相關標籤/搜索