JavaScript的各種函式
定義函式的方式
常見定義函式的方式有這幾種:
- 函式宣告(Function Declaration)
- 函式運算式(Function Expressions)
- 透過
new Function關鍵字建立函式 - Bind(綁定 this 後產生新函式)
- 箭頭函式(Arrow Function)
下面我們一一介紹。
函式宣告(Function Declaration)
「函式宣告」應該是屬於最常見的用法:
function 名稱([參數]) {
// 做某事
}
像本篇一開始的範例就是用這種方式:
function square(number) {
return number * number;
}
函式運算式(Function Expressions)
另一種方式,則是透過 變數名稱 = function([參數]){ ... }; 的方式,將一個函式透過 = 指定給某個變數。
像這樣:
var square = function (number) {
return number * number;
};
可能有些人會覺得這樣很奇怪,但還記得我們一直強調的嗎?函式實際上它仍屬於 Object 的類型,是一種可以被呼叫 (be invoked) 的特殊物件 (值),自然可以透過變數存入囉。
沒有名字的函式?
是的,聰明的你也許已經察覺到了,在範例裡 = 後面的 function 是「沒有名字」的:
var square = function (number) {
return number * number;
};
像這類沒有名字的函式在 JavaScript 是合法的,通常我們會稱它為「匿名函式」。匿名函式我們等等還會見到,現在先介紹到這裡。
在函式運算式中,如果想要在 function 後面加上一個名字是可以的嗎?可以,像這樣:
var square = function func(number) {
return number * number;
};
但是要注意的是,這個名字只在「自己函式的區塊內」有效,也就是說:
var square = function func(number) {
console.log( typeof func );// "function"return number * number;
};
console.log( typeof func );// undefined
像這樣,脫離了函式自身區塊後,變數 func 就不存在了。
當然,在「匿名函式」的函式運算式情況下,你還是可以透過自定義的變數名稱取得 function,沒有一定要替這個函式取名的理由:
var square = function func(number) {
console.log( typeof square );// "function"return number * number;
};
透過 **new Function** 關鍵字建立函式
最後一種方式就是直接使用 Function (注意 F 大寫) 這個關鍵字來建立函式物件。 使用時將參數與函式的內容依序傳入 Function,就可以建立一個函式物件了。 像這樣:
Function constructor:使用 Function 構造函數創建一個新的函數
// 透過 new 來建立 Function "物件"
var square = new Function('number', 'return number * number');
const divide = new Function("a", "b", "return a / b;");
透過 new Function 所建立的函式物件,每次執行時都會進行解析「字串」(如 'return number * number' ) 的動作,運作效能較差,所以通常實務上也較少會這樣做。
但不管是透過哪一種方式定義函式,呼叫函式的話就直接用「函式名稱(參數)」的方式,像 square(2); 就可以了。 [註1]
Bind:使用函數的 bind 方法創建一個新的函數,並綁定 this 的值。
const person = {
name: "John Doe",
greet: function () {
console.log(`Hello, my name is ${this.name}`);
}
};
const greet = person.greet.bind(person);
greet();
// Output: Hello, my name is John Doe
箭頭函式(Arrow Function)
const add = (a, b) => a + b;
console.log(add(1, 2)); // 3
箭頭函數的一個特點是,它的 this 關鍵字不會被動態改變,它總是繼承自它外層作用域的 this。例如:
const object = {
name: 'John Doe',
greet: () => {
console.log(`Hello, my name is ${this.name}.`);
}
};
object.greet(); // Hello, my name is undefined.