JavaScript 語言核心(9)不可輕忽的函式基礎
JavaScript 語言核心(8)數字為特性的陣列 << 前情 對於要重複執行的內容,你可以使用 function max(num1, num2) { return num1 > num2 ? num1 : num2; } console.log(max(10, 20)); // 20 在上面的例子示範了函式的基本宣告與呼叫方式。函式使用 在函式上的參數宣告,只是傳入引數的具名參考,實際上,宣告函式時若傳入的引數少於參數是可行的,不足的部份,參數就是 function func(a, b) { console.log(a); console.log(b); } func(10, 20); // 10 20 func(10); // 10 undefined func(); // undefined undefined func(10, 20, 30, 40); // 10 20 在上例中,你也看到了,就算傳入比參數個數還多的引數也是可行的,那多的引數跑到哪去了?事實上,在函式內部會自動宣告 function sum() { var sum = 0; for(var i = 0; i < arguments.length; i++) { sum += arguments[i]; } return sum; } console.log(sum(1, 2));; // 3 console.log(sum(1, 2, 3)); // 6 console.log(sum(1, 2, 3, 4)); // 10
在 EMCAScript 5 前的版本,參數只是具名的引數,你改變參數的值, function func(a, b) { console.log(a + ': ' + arguments[0]); // 10: 10 console.log(b + ': ' + arguments[1]); // 20: 20 a = 0; b = 0; console.log(a + ': ' + arguments[0]); // 0: 0 console.log(b + ': ' + arguments[1]); // 0: 0 arguments[0] = 100; arguments[1] = 200; console.log(a + ': ' + arguments[0]); // 100: 100 console.log(b + ': ' + arguments[1]); // 200: 200 } func(10, 20); 然而,若採用 EMCAScript 5 嚴格模式,參數的值 與 'use strict' function func(a, b) { console.log(a + ': ' + arguments[0]); // 10: 10 console.log(b + ': ' + arguments[1]); // 20: 20 a = 0; b = 0; console.log(a + ': ' + arguments[0]); // 0: 10 console.log(b + ': ' + arguments[1]); // 0: 20 arguments[0] = 100; arguments[1] = 200; console.log(a + ': ' + arguments[0]); // 0: 100 console.log(b + ': ' + arguments[1]); // 0: 200 } func(10, 20); 當然,改變參數值本身也不是個好的實踐,應該避免!ECMAScript 5 的嚴格模式下,也不允許重複的參數名稱。例如,以下將會發生 'use strict' function func(a, a, b) { // 做些事 ... } 由於呼叫函式時傳入的引數個數不一定要等於參數個數,因此若要確認引數等於參數個數,可透過 function plus(a, b) { if(arguments.length != 2) { throw new Error('必須有兩個引數'); } return a + b; } console.log(plus(10, 20)); // 30 console.log(plus(10)); // Error: 必須有兩個引數 事實上,在 JavaScript 程式設計上的慣例,很少檢查引數個數,而是在引數不足時提供預設值,這很容易辦到,因為引數不足時,不足的參數會是 function rangeClosed(startInclusive, endInclusive, step) { var s = step || 1; var numbers = [startInclusive]; for(var i = 0; numbers[i] < endInclusive; i++) { numbers.push(numbers[i] + s); } return numbers; } rangeClosed(1, 5, 2).forEach(function(elem) { // 1 3 5 console.log(elem); }); rangeClosed(1, 5).forEach(function(elem) { // 1 2 3 4 5 console.log(elem); }); 在上例是一個數值產生器, 如果在選項非常多時,還會採用選項物件(Option object)的方式。例如: function func(option) { var opt = { x : option.x || 10, y : option.y || 20, z : option.z || 30 }; console.log(opt.x); console.log(opt.y); console.log(opt.z); } func({x : 100}); // 100 20 30 func({ // 100 200 30 x : 100, y : 200 }); func({ // 100 200 300 x : 100, y : 200, z : 300 }); 在上例中,呼叫函式時必須提供物件,物件上帶有函式所需的資料,函式內部對於物件上沒有提供資料時,會提供預設值。 你可以在陳述句(像是 'use strict' if(true) { // SyntaxError: In strict mode code, functions can only be declared at top level or immediately within another function. function func(a) { console.log(a); } } |