8/16/2013
1:56:00 PM 0

JavaScript function 的兩種宣告方式

寫法一
function subtract(a, b){
    return a - b;
};
寫法二
var subtract = function (a, b) {
    return a - b;    
};

這是兩種不同的 function 宣告方式

第一種寫法是 Function Declaration

產生 execute context 階段時 Function Declaration 就已存到 VO(Variable Object), 所以在執行階段(Execution Stage), 函式就已先存在, 造成的結果是程式呼叫的位置可以比程式宣告更前面
var result = subtract(1,2);

function subtract(a, b){
    return a - b;
};

第二種寫法是 Function Expression

Function Expression 寫法在執行階段才建立,並且不會被存在變數物件(VO)中, 可依照條件建立 Function Expression
var num = 11;

var test = (num % 2 == 0
    ? function () { alert("The number is even."); }
    : function () { alert("The number is odd."); }
);
  
test();

兩種寫法的差異只有在執行階段產生先後的差別, 而效能會根據所使用的 Javascript engine 而有不同的結果, 至於哪種寫法比較好? 我認為要根據個人習慣和程式碼的易讀和維護來做選擇了

國外高手做的 function declaration vs function expression 效能測試網頁, 有興趣可以玩玩看
http://jsperf.com/function-declaration-vs-function-expression

做個綜合練習
function outside1(){
    function inside1() {
        return 0;
    }
    return inside1();
    function inside1() {
        return 1;
    }
}
alert(outside1());


alert(outside2());
function outside2(){
    var inside2 = function() {
        return 0;
    };
    return inside2();
    var inside2 = function() {
        return 1;
    };
}


function outside3(){
    return inside3();
    var inside3 = function() {
        return 0;
    };
    var inside3 = function() {
        return 1;
    };
}
alert(outside3());
執行結果  1,0,TypeError: undefined is not a function

網路上看到一個有趣的例子 http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html
var a = 1;
function b() {
    a = 10;
    return;
    function a() {}
}
b();
alert(a);
執行結果是1

這例子直覺上應該是印出10, 因為 function b 第一行就改變了全域變數 b, 這例子利用 Function Declaration  在執行階段前就已產生的特性, 讓人稍不注意就產生了混淆

原因在前面有說過 function Declaration 會造成執行階段前函式就已存在, 所以處理 function b 的 function context 時, 區域變數 a 就已經先被建立起來, 而這時此變數指向一個函式,當執行階段處理 a = 10; interpreter 會先檢查目前的 execute context 有沒有這個變數, 結果發現了 function a, 因此把 10 指定給他, 所以 a = 10, 是改變了區域變數 a  而不是全域變數的 a, 在 a = 10 前後加上 alert 就可證明這一點

這下面這種狀況就不可使用 Function Declaration 寫法
if (true) {
  function sayHello() {
    return 'Hello 1';
  }
}
else {
  function sayHello() {
    return 'Hello 2';
  }
}
sayHello();
必須使用 Function Expression 的寫法
var sayHello;
if (true) {
  sayHello = function() {
    return 'Hello 1';
  };
}
else {
  sayHello = function() {
    return 'Hello 2';
  };
}
sayHello();

0 comments:

Post a Comment