我們可以把 JavaScript Function 當作是 可執行的物件。
JavaScript Function 有兩大特性:
其中,Scope 的部分將會留到下一篇介紹。
Function 是 JavaScript 的 First-class object,那何謂 First-class object 呢? 簡單來講就是
對物件型別能做的事情,也能對 Function 做
也就是我們能夠:
就讓我們來一一驗證。
function myFunction() {
console.log('This is myFunction');
}
var a = myFunction,
myObj = { fn: myFunction };
console.log(a); // f myFunction() { console.log('This is myFunction'); }
console.log(myObj.fn); // f myFunction() { console.log('This is myFunction'); }
a(); // "This is myFunction"
myObj.fn(); // "This is myFunction"
從範例中能看到,function 可以被自由的指派給其他變數的,當我們印出 a
/myObj.fn
的時候,就會 log 出整個 myFunction
的內容。此時 變數/屬性 的內容是 myFunction,因此當我們加上 ()
時,就會執行 myFunction
。
function myFunction() {
console.log('This is myFunction');
}
myFunction.prop1 = 'This is prop1';
console.log(myFunction.prop1); // "This is prop1"
myFunction(); // "This is myFunction"
如同 物件一樣,我們可以自由的在 Function 上加上屬性,並且就算加完了屬性,Function 還是可以正常運作。
也就是說,Function 可以搭配各種運算元使用,甚至也可以放在 if
中判斷他是 truthy 還是 falsy。
在這邊,我們用之前提到的 NOT 運算元 !
來試試看能不能將 function 放入 Expression 中:
function myFunction() {
console.log('This is myFunction');
}
console.log(!myFunction); // false
結果讓我們確定 function 也可以加入 Expression,因為 function 不在 falsy
之列,經由 NOT 運算元後印出的就會是 false
。
如物件一樣,我們能夠在任何地方宣告 function,例如,在 function 中還能在宣告一個 function,甚至也能在傳入參數時宣告。不論是何種宣告方式,這些 function 都是可以正常執行的:
function myFunction(callback) {
console.log('This is myFunction'); // This is myFunction
callback(); // This is myCallback
function myInnerFunction() {
console.log('This is myInnerFunction');
}
myInnerFunction(); // This is myInnerFunction
}
myFunction(function myCallback() {
console.log('This is myCallback');
});
由上面四個範例中,我們都可以看到 Function 會有物件所有的特性,物件與 Function 的差別只在於 Function 是可以被執行的,因此說我們才說 Function 是一個可執行物件。
宣告 function的方式主要三種:
Function delclaration 是最基本宣告 function 的方式,與其他語言宣告 function 的方法相同:
function myFunction() {
console.log('Function declared with Function declaration');
}
如上面所提,Function 可以被傳遞給其他參數儲存。如字面值一般,Function 也可以在定義的同時賦予變數,這種方法就稱為 Function Expression,如下所示:
var myFunction = function NamedFunction() {
console.log('Function declared with Function expression');
}
myFunction(); // "Function declared with Function expression"
另外,因為利用 Function Expression 會將 Function 傳遞給一個變數,因此 JavaScript 允許 Function 搭配 匿名函式(不具名字的函式) 使用:
var myFunction = function() {
console.log('Function declared with Function expression');
}
myFunction(); // "Function declared with Function expression"
透過以上兩個範例,可以看到不論是以 具名函式 或是以 匿名函式,執行出來的結果都是相同的。
與其他的 內建物件型別 相同,Function 也可以利用 new
來新增物件:
var myFunction = new Function("parameter1", "parameter2", "console.log('Function declared with Function Constructor')");
myFunction(); // Function declared with Function Constructor
事實上,以上的程式碼可以用 Function Expression 取代
var myFunction = function(parameter1, parameter2) {
console.log('Function declared with Function expression')
}
myFunction(); // "Function declared with Function expression"
因此同樣的,少用new
,以 Function Expression 取代 new
來增加易讀性與效能。
function 的呼叫方式有三種:
new
呼叫在 Function 後面加上 ()
就可以呼叫 Function,例如:
myFunction();
Function 中有兩種內建的函式可以用來呼叫 Function
call
apply
那為何不使用 ()
來執行 Function 就好呢? 因為他們有 明確指定 this 的功能。
this
與 call
、apply
的詳細運作原理也會在之後的章節中討論。首先我們還是先上範例:
var myFunction = function(parameter1, parameter2) {
console.log(parameter1, parameter2);
}
myFunction.call(null, 'hello world', 123); // "hello world" 123
myFunction.apply(null, ['hello world', 123]); // "hello world" 123
如結果所示,call
與 apply
執行 Function 的功能與 ()
無異。
call
與 apply
的差別在於 apply
的第二個參數是一個陣列,裡面帶有要傳入 function 中的參數。因此在範例中,我們可以看到 apply
的第二個參數為 ['hello world', 123]
,這兩個參數會被攤開為 parameter1
與 parameter2
後放入 myFunction
執行。
new
呼叫使用 new
代表將 Function 當作建構式來使用,會回傳子型別為該 Function 的物件。new
詳細的介紹也會在往後篇幅中涵蓋。
使用 new
與宣告內建物件型別的方法是一樣的:
function myFunction() {
console.log('Function declared with Function expression');
}
var a = new myFunction(); // "Function declared with Function expression"
console.log(a); // myFunction {}
或稱:自我調用函式 ( Self-Invoking Functions )
顧名思義,IIFE 有兩個特性:
(function() {
// codes here
})();
讓我們來看看範例:
(function() {
console.log('This is IIFE'); // "This is IIFE"
})();
哇 IIFE 真的不需要再額外呼叫就會自己就執行了。其實重點除了在於包裹 function 的 ()
以外,還有用來呼叫 function 的 ()
。
()
呼叫讓我們試試不加呼叫 Function 的 ()
會怎樣:
(function() {
console.log('This is IIFE');
});
什麼都沒發生。因此在使用 IIFE 的時候後面務必加上 ()
。
除此之外,IIFE 依然可以回傳值,如下:
var myString = (function() {
return 'This is IIFE';
})();
console.log(myString); // This is IIFE
myString
可以接收到 IIFE 自動執行完後回傳的字串。IIFE 除了會自動執行以外,與一般 function 的特性都是一模一樣的。
new
使用,則稱為 建構式 ( constructor )
本篇中,我們介紹了 Function 相關內容,包括
JavaScript Function 有兩大特性:
First-class Object:
宣告 Function 的方式:
呼叫 Function 的方式:
new
呼叫https://www.w3schools.com/js/js_function_definition.asp
https://www.w3schools.com/js/js_function_invocation.asp