JavaScript基礎5——關於ECMAscript的函數

  • ECMAScript的函數概述(通常定義到<head>標籤之間)

(1)定義函數,JavaScript通常有三種定義函數方法:
*第一種是使用function語句定義函數(靜態方法)
javascript

1 function 函數名(var1,var2,...,varX)
2      {
3 
4          代碼...(return)
5 
6      }


第二種是使用Function()構造函數來定義函數(不經常使用)
html

1 var 函數名 = new Function(「參數1」,」參數2」,」參數3」……」函數體」);
2 如:
3 var 函數名 = new Function(」x」,」y」,」var z=x+y;return z;」);

 
*第三種是在表達式中定義函數
java

1 var 函數名 = function(參數1,參數2,…){函數體};
2 //例如:
3 //定義
4 var add = function(a,b){
5 return a+b;
6 }
7 //調用函數
8 document.write(add(50,20));

 

(2)函數做用域:瀏覽器

       函數外面定義的變量是全局變量,在整個HTML頁面內都有效(生存期在整個HTML頁面)。,函數內能夠直接使用。在函數內部沒有使用var定義的,變量則爲全局變量,*在函數內使用var關鍵字定義的變量是局部變量,即出了函數外邊沒法獲取。js函數定義的參數沒有默認值。(目前只有最新的火狐瀏覽器支持)
閉包

 

(3)如何調用函數:函數

//sayHi函數
function sayHi(sName, sMessage) {

  alert("Hello " + sName + sMessage);

}

//調用上面的函數 sayHi(),會生成一個警告窗口
sayHi("David", " Nice to meet you!")

 

(4)函數如何返回值:spa

函數 sayHi() 未返回值,即便函數確實有值,也沒必要明確地聲明它。該函數只須要使用 return 運算符後跟要返回的值便可。設計

 1 function sum(iNum1, iNum2) {
 2 
 3   return iNum1 + iNum2;
 4 
 5 }
 6 
 7 //下面的代碼把 sum 函數返回的值賦予一個變量:
 8 
 9 var iResult = sum(1,1);
10 
11 alert(iResult);    //輸出 "2"

另外一個重要概念是,與在 Java 中同樣,函數在執行過 return 語句後當即中止代碼。所以,return 語句後的代碼都不會被執行。調試

1 function sum(iNum1, iNum2) {
2 
3   return iNum1 + iNum2;
4 //alert 窗口就不會顯示出來
5   alert(iNum1 + iNum2);
6 
7 }

一個函數中能夠有多個 return 語句,以下所示:code

 1 function diff(iNum1, iNum2) {
 2 
 3   if (iNum1 > iNum2) {
 4 
 5     return iNum1 - iNum2;
 6 
 7   } else {
 8 
 9     return iNum2 - iNum1;
10 
11   }
12 
13 }

上面的函數用於返回兩個數的差。要實現這一點,必須用較大的數減去較小的數,所以用 if 語句決定執行哪一個 return 語句。

若是函數無返回值,那麼能夠調用沒有參數的 return 運算符,隨時退出函數。

 1 function sayHi(sMessage) {
 2   if (sMessage == "bye") {
 3 
 4     return;
 5 
 6   }
 7 
 8   alert(sMessage);
 9 
10 }
11 //這段代碼中,若是 sMessage 等於 "bye",就永遠不顯示警告框
12 
13 //註釋:若是函數無明確的返回值,或調用了沒有參數的 return 語句,那麼它真正返回的值是 undefined。

 

  • 關於函數的arguments對象

在函數代碼中,使用特殊對象 arguments,開發者無需明確指出參數名,就能訪問它們。

例如,在函數 sayHi() 中,第一個參數是 message。用 arguments[0] 也能夠訪問這個值,即第一個參數的值(第一個參數位於位置 0,第二個參數位於位置 1,依此類推)。

所以,無需明確命名參數,就能夠重寫函數:

1 function sayHi() {
2   if (arguments[0] == "bye") {
3     return;
4   }
5   alert(arguments[0]);
6 }

1.檢測參數個數

        還能夠用 arguments 對象檢測函數的參數個數,引用屬性 arguments.length 便可。下面的代碼將輸出每次調用函數使用的參數個數:

 1 function howManyArgs() {
 2 
 3 alert(arguments.length);
 4 
 5 }
 6 
 7 howManyArgs("string", 45);
 8 howManyArgs();
 9 howManyArgs(12);
10 
11 //上面這段代碼將依次顯示 "2"、"0" 和 "1"。
12 //與其餘程序設計語言不一樣,ECMAScript 不會驗證傳遞給函數的參數個數是否等於函數定義的參數個數。開發者定義的函數均可以接受任意個數的參數(根據 Netscape 的文檔,最多可接受 25 個),而不會引起任何錯誤。任何遺漏的參數都會以 undefined 傳遞給函數,多餘的函數將忽略。

 

2.模擬函數重載

用 arguments 對象判斷傳遞給函數的參數個數,便可模擬函數重載:

 1 function doAdd() {
 2 
 3   if(arguments.length == 1) {
 4 
 5     alert(arguments[0] + 5);
 6 
 7   } else if(arguments.length == 2) {
 8 
 9     alert(arguments[0] + arguments[1]);
10 
11   }
12 }
13 doAdd(10);    //輸出 "15"
14 
15 doAdd(40, 20);    //輸出 "60"
16 
17 //當只有一個參數時,doAdd() 函數給參數加 5。若是有兩個參數,則會把兩個參數相加,返回它們的和。因此,doAdd(10) 輸出的是 "15",而 doAdd(40, 20) 輸出的是 "60"。雖然不如重載那麼好,不過已足以避開 ECMAScript 的這種限制。
  • Function對象(類)

1. Function對象的使用

函數其實是功能完整的對象。Function 類能夠表示開發者定義的任何函數。用 Function 類直接建立函數的語法以下:var function_name = new function(arg1, arg2, ..., argN, function_body)。

 1 <html>
 2 
 3 <head>
 4 
 5 <script type="text/javascript">
 6 
 7      var sayHi = new Function("sName", "sMessage", "alert(\"Hello \" + sName + sMessage);");
 8 
 9 </script>
10 
11 </head>
12 
13 
14 <body>
15 
16 <script type="text/javascript" >
17 
18      sayHi("Jackie","Welcome here!");//調用函數
19 
20 </script>
21 
22 </body>
23 
24 </html>

儘管能夠使用 Function 構造函數建立函數,但最好不要使用它,由於用它定義函數比用傳統方式要慢得多。不過,全部函數都應看做 Function 類的實例。

2. 使用Function類的length屬性

 1 <html>
 2 
 3 <head>
 4 
 5 <script type="text/javascript">
 6 
 7      function fun1(){}
 8 
 9      function fun2(a1,a2){}
10 
11      function fun3(a1,a2,a3,a4,a5,a6,a7){}
12 
13 </script>
14 
15 </head>
16 
17  
18 <body>
19 
20 <script type="text/javascript">
21 
22      document.write(fun1.length+" "+fun2.length+" "+fun3.length);
23 
24 </script>
25 
26 </body>
27 
28 </html>

使用Function的length屬性能夠獲得函數的形參個數。

3. 使用Function類的valueOf()方法和toString()方法。這兩個方法返回的都是函數的源代碼,在調試時尤爲有用。

 

 1 <html>
 2 
 3 <head>
 4 
 5 function fun() {
 6 
 7   alert("Hi");
 8 
 9 }
10 
11 </head>
12 
13 <body>
14 
15 <script type="text/javascript">
16 
17      document.write(fun.toString());//輸出函數的源代碼
18 
19 </script>
20 
21 </body>
22 
23 </html>
  • 閉包

ECMAScript 最易讓人誤解的一點是,它支持閉包(closure)。閉包,指的是詞法表示包括不被計算的變量的函數,也就是說,函數能夠使用函數以外定義的變量。

1.簡單的閉包實例

在 ECMAScript 中使用全局變量是一個簡單的閉包實例。請思考下面這段代碼:

 

1 var sMessage = "hello world"; 
2 
3 function sayHelloWorld() {
4 
5  alert(sMessage);//使用函數以外定義的變量
6 
7  } 
8 
9 sayHelloWorld(); 

 

在上面這段代碼中,腳本被載入內存後,並無爲函數 sayHelloWorld() 計算變量 sMessage 的值。該函數捕獲 sMessage 的值只是爲了之後的使用,也就是說,解釋程序知道在調用該函數時要檢查 sMessage 的值。sMessage 將在函數調用 sayHelloWorld() 時(最後一行)被賦值,顯示消息 "hello world"。

2.複雜的閉包實例

在一個函數中定義另外一個會使閉包變得更加複雜。例如:

 

 1 var iBaseNum = 10; 
 2 
 3 function addNum(iNum1, iNum2) {
 4  
 5     function doAdd() { 
 6 
 7           return iNum1 + iNum2 + iBaseNum; 
 8 
 9      } 
10 
11     return doAdd();
12  
13 } 

 

這裏,函數 addNum() 包括函數 doAdd() (閉包)。內部函數是一個閉包,由於它將獲取外部函數的參數 iNum1 和 iNum2 以及全局變量 iBaseNum 的值。 addNum() 的最後一步調用了 doAdd(),把兩個參數和全局變量相加,並返回它們的和。

這裏要掌握的重要概念是,doAdd() 函數根本不接受參數,它使用的值是從執行環境中獲取的。能夠看到,閉包是 ECMAScript 中很是強大多用的一部分,可用於執行復雜的計算。

提示:就像使用任何高級函數同樣,使用閉包要當心,由於它們可能會變得很是複雜。

  • JavaScript函數的思惟導圖

相關文章
相關標籤/搜索