JavaScript 函式的兩種宣告方式

艾倫先生發表於2017-12-14

1.函式宣告的方式

JavaScript宣告函式有兩種選擇:函式宣告法,表示式定義法。

  • 函式宣告法

      function sum (num1 ,num2){   
          return num1+num2  
      } 
    複製程式碼
  • 表示式定義法

      var sum = function(num1,num2){   
          return num1+num2  
      };
    複製程式碼

2.扒一扒兩種函式宣告的區別

解析器會率先讀取函式宣告(也就是說函式宣告的優先順序較高),並使其在執行任何程式碼之前可以訪問(將函式宣告提升到程式碼樹頂部);至於函式表示式宣告,則必須等到解析器執行到它所在的程式碼行,才會執行,無法自動提升。

同樣的函式使用不同的定義方式,呼叫的時候會產生不同的效果。

// 函式宣告法
var num = add(1, 2);
console.log(num);// 3

function add(a, b) {
    return a + b
}

// 函式表示式宣告
var num = add(1, 2);
console.log(num);//Uncaught TypeError: undefined is not a function 

var add = function (a, b) {
    return a + b
}
複製程式碼

我們來看一看這兩種宣告方式到底對程式碼產生了怎樣的影響。

首先看函式宣告,由於發生了程式碼提升,實際的程式碼如下

// 函式宣告法
function add(a, b) {
    return a + b
}
var num = add(1, 2);
console.log(num);// 3

//function add(a, b) {
//    return a + b
//}
複製程式碼

再看錶達式宣告法,同樣將變數add提升,add()函式呼叫的時候,只宣告瞭變數add,卻沒有進行賦值。(此時的add變數是undefined)實際的程式碼如下。

// 函式表示式宣告
var add;
var num = add(1, 2);
console.log(num);//Uncaught TypeError: undefined is not a function 

add = function (a, b) {
    return a + b
}
複製程式碼

3.關於變數提升和執行順序

JavaScript是解釋型語言,但它並不是逐行執行的。解析過程可以理解為兩個階段:一個是預處理階段,JavaScript將指令碼程式碼轉換為位元組碼,該過程中將所有定義的變數提升到程式碼樹頂端;第二個階段,JavaScript直譯器藉助執行環境,把位元組碼生成機械碼,該過程中才發生變數的賦值,並順序執行。

console.log(a); 
//Error:a is not defined ,直接報錯,下面語句沒法執行,以下結果為註釋該句後結果  
console.log(b) //undefined  ,變數發生提升
var b="Test";  
console.log(b);//Test  
複製程式碼

也就說JavaScript值執行第一句語句之前就已經將函式/變數宣告預處理了

var b="Test" 相當於兩個語句

var b;(undefined結果的來源,在執行第一句語句之前已經解析)

b=”Test”(這句是順序執行的,在第二句之後執行)

這也是為什麼我們可以在方法宣告語句之前就呼叫方法的原因。

4.練一練

下面我們用一個經典的面試題目的一部分來對本篇文章進行總結

請問下面這段程式碼的執行結果是什麼?

function Foo() {      
    getName = function () {   
        alert (1);   
    };      
    return this;  
}  
  
Foo.getName = function () {   
    alert (2);  
};  
  
Foo.prototype.getName = function () {   
    alert (3);  
};  
  
var getName = function () {   
    alert (4);  
};  
  
function getName() {   
    alert (5);  
}  


getName() 
複製程式碼

答案載入中...

答案載入中...

答案載入中...

答案載入中...

答案載入中...

答案載入中...

答案載入中...

答案載入中...

答案載入中...

答案載入中...

答案載入中...

答案載入中...

答案載入中...

答案載入中...

揭曉答案:

4

這裡我主要講解一下第二問中為什麼是4,其他的在後續文章中進行說明。上面的程式碼實際上是這個樣子滴

function Foo() {      
    getName = function () {   
        alert (1);   
    };      
    return this;  
}  
var getName;//只提升變數宣告  
function getName() { //提升函式宣告,覆蓋var的宣告  
    alert (5);  
}  
Foo.getName = function () {   
    alert (2);  
};  
Foo.prototype.getName = function () {   
    alert (3);  
};  
getName = function () { //最終的賦值再次覆蓋function getName宣告  
    alert (4);  
};  
getName();//最終輸出4  
複製程式碼

這下大家對函式宣告和函式表示式宣告,以及程式碼執行順序的基本知識就有所掌握了吧,歡迎批評指標~

相關文章