JavaScript 流程控制 - function函式

function函式組成

function name(){
  statement
} 

(arguments),括號內可有一或多個參數。當資料做為參數而傳入函式,它的行動就像函式內已初始化的區域參數;雖然函式參數的行為很像函式內的區域變數,在函式內改變參數,卻不會影響函式外的任何事物。

function函式回傳資料

使用return關鍵字來回傳資料。

function name(){
  statement
  return value;
}

函式只要碰到return後立刻結束。技巧:在流程控制上,我們也可以使用沒有回傳值的return來結束函式。return不只回傳資料,也負責結束函式。

function name(){
  statement
  return;
} 

所以函式的回傳值會取代了函式的呼叫。例如,

// 假設有一計算價錢的函式cale(),參數number傳入數量,會得到金額
totalPrice = cale(number);
// cale()函式計算後會return price;
// 最後會以回傳值取代函式的呼叫,可以看成:totalPrice = price; 來得到最終的結果 

function is data

函式實字(function literal)

當函式本體單獨出現,沒有名稱。把函式本體看成值,把函式名稱看為變數名稱。

var showMsg = function(Msg){
  alert(Msg);
} 

showMsg:函式名稱(函式參考),即變數名稱。

function(){...}:把function(函式實字)當成變數值。

函式實字讓函式能像變數般操縱,例如,

var myMessage = showMsg;

指派showMsg()函式給變數myMessage。以上程式碼表示函式也能利用變數語法而建立,甚至組成元件也相同。指派函式名稱給另一個變數,就是為了讓變數可以取用函式本體。

alert(myMessage("Hello World!")); 

function reference, 函式參考

呼叫showMsg()與myMessage的結果相同,因為兩個函式最後都參考(reference)了相同的原始碼,因此函式名稱也稱函式參考(function reference)。

函式其實只是「值」參考到函式本體的變數。

函式參考與函式呼叫

函式參考只會單獨出現,例如,

var myMessage = showMsg; 

對myMessage指派函式參考。函式呼叫則必定後隨括號( ),很多時候還附有參數,例如,

myMessage("Hello World!"); 

呼叫myMessage()與showMsg()相同。

參考重要性

函式參考不像一般變數,變數的資料儲存成記憶體的某個區段,函式則儲存對原始碼的參考,函式變數的值不是原始碼本身,而是指向儲存原始碼的記憶體位置的指標,函式使用參考,而非實際的值,比起儲存多份函式碼的複本,參考有效率多了。



回呼函式

又稱callback function沒有直接操作,也能呼叫函式;回呼函式被瀏覽器呼叫,以回應發生在JavaScript外的事情。最常使用在處理事件,例如:

<body onload="init();"> 
把init()函式連接上onload事件。又例如:

<input type="button" id="birthday" onclick="checkFormat("YYYY/MM/DD");" /> 

把checkFormat()函式連接上onclick事件,但這不合乎JavaScript與HTML「分離」原則。

使用回呼函式連接事件

window.onload=init; 
onload事件是window物件的屬性,init函式名稱後面沒有括號,此時並非執行函式,只是想參考函式,白話:把init函式的參考指派給window物件的onload事件。函式參考沒有提供透過參數傳遞資料的方式,我們可以使用「函式實字(function literal)」做為函式參考,而後從函式實字內呼叫函式。

document.getElementById("birthday").onclick = function(evt){
  checkFormat("YYYY/MM/DD");
} 

function(evt){...} 函式實字被指派給 onclick 事件,做為函式參考。函式實字包著對函式的呼叫,所以你可以把函式實字想成處理事件的無名函式,因此函式實字又稱「匿名函式」(anonymous function),透過evt,可以傳入事件處理器的事件物件(event object),事件物件包含各個事件特有的資訊。函式實字建立匿名事件處理函式。

自訂函數

function fnName([arg0, arg1, ...]){
  statements
  [return [expression]];
} 

arguments物件,就算自訂函數沒有定義傳入的參數,arguments物件可以取得傳入的參數值,arguments[0]即可取得第一個參數的參考。ECMAScript不會驗證傳遞給函數的參數個數是否等於函數定義的參數個數,任何自訂的函數都可以接受任意個數的參數,而不會引發錯誤。任何遺漏的參數都會以undefined的型式傳遞給函數,而多餘的參數將會被自動忽略。

內建函數 - 編碼轉換函數

  • escape(String)/unescape(String)
    將字串進行URL編碼,不建議使用。
    • 英文字母和數字 :不進行編碼
    • 空白與標點符號:轉換成%XX字串,XX為16進位值,例如,空白為%20
    • 中文字:轉換成%uXXXX,XXXX為16進位值,例如,網為%u7DB2
  • encodeURI()/decodeURI()
    複雜度比escape()還高,將字串加密成URI字串。
  • encodeURIComponent()/decodeURIComponent()
    複雜度比encodeURI()還高,將字串加密成URI字串,連符號字元都會轉換。

URI - Universal Resource Index

Internet資源的標準格式,將所有非英文字母的字元轉換成%XY格式,XY為字元的ASCII碼,使用ISO Latin-1字元集。

傳值(Value)或傳址(Address)

  • Value:只是將變數的值傳入函數,函數會另外配置記憶體儲存參數值,所以不會變更原變數的值
  • Address:將變數實際儲存的記憶體位置傳入,所以如果在函數中變更參數值,會同時變動原變數值

JavaScript型別預設傳遞

JavaScript型別預設傳遞Value或Address
型別傳遞說明
數字、字串、布林Value參數傳遞和比較都是使用Value方式
物件、陣列、函數Address參數傳遞和比較都是使用Address方式
字串物件Address參數傳遞和比較都是使用Address方式

這邊注意一下,字串與字串物件這兩者是不同的傳遞方式。

// 字串
var s1, s2
s1 = "KKBruce"
s2 = s1

// 字串物件
var s3 = new String();

變數範圍 - 區域與全域

  • 區域變數(Local Variables):在函數內宣告的變數,只能在函數內的程式區塊使用
  • 全域變數(Global Variables):變數在函數外宣告,整個JavaScript程式的函數和程式碼都可以存取

使用function函式的時機

  • 複製原始碼是個好徵兆
  • 某段原始碼逐漸變得笨重龐大,可以把它切成數個邏輯片段

沒有留言:

張貼留言

感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。