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