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