一、ECMAScript 函數(shù)概述
1、什么是函數(shù)?
函數(shù)是一組可以隨時隨地運行的語句。
函數(shù)是 ECMAScript 的核心。
函數(shù)是由這樣的方式進行聲明的:關(guān)鍵字 function、函數(shù)名、一組參數(shù),以及置于括號中的待執(zhí)行代碼。
函數(shù)的基本語法是這樣的:
function functionName(arg0, arg1, ... argN) {
statements
}
例如:
function sayHi(sName, sMessage) {
alert("Hello " + sName + sMessage);
}
2、如何調(diào)用函數(shù)?
函數(shù)可以通過其名字加上括號中的參數(shù)進行調(diào)用,如果有多個參數(shù)。
如果您想調(diào)用上例中的那個函數(shù),可以使用如下的代碼:
sayHi("David", " Nice to meet you!")
調(diào)用上面的函數(shù) sayHi() 會生成一個警告窗口。
3、函數(shù)如何返回值?
函數(shù)只需要使用return運算符后跟要返回的值即可。
函數(shù)在執(zhí)行過 return 語句后立即停止代碼。因此,return 語句后的代碼都不會被執(zhí)行。
注釋:如果函數(shù)無明確的返回值,或調(diào)用了沒有參數(shù)的 return 語句,那么它真正返回的值是 undefined。
二、ECMAScript arguments 對象
1、arguments 對象
在函數(shù)代碼中,使用特殊對象 arguments,開發(fā)者無需明確指出參數(shù)名,就能訪問它們。
例如,在函數(shù) sayHi() 中,第一個參數(shù)是 message。用 arguments[0] 也可以訪問這個值,即第一個參數(shù)的值(第一個參數(shù)位于位置 0,第二個參數(shù)位于位置 1,依此類推)。
因此,無需明確命名參數(shù),就可以重寫函數(shù):
function sayHi() {
if (arguments[0] == "bye") {
return;
}
alert(arguments[0]);
}
2、檢測參數(shù)個數(shù)
還可以用 arguments 對象檢測函數(shù)的參數(shù)個數(shù),引用屬性 arguments.length 即可。
function howManyArgs() {
alert(arguments.length);
}
howManyArgs("string", 45);
howManyArgs();
howManyArgs(12);
上面這段代碼將依次顯示 "2"、"0" 和 "1"。
注釋:
- ECMAScript 不會驗證傳遞給函數(shù)的參數(shù)個數(shù)是否等于函數(shù)定義的參數(shù)個數(shù)。
- 開發(fā)者定義的函數(shù)都可以接受任意個數(shù)的參數(shù)(根據(jù) Netscape 的文檔,最多可接受 255 個),而不會引發(fā)任何錯誤。
- 任何遺漏的參數(shù)都會以 undefined 傳遞給函數(shù),多余的函數(shù)將忽略。
3、模擬函數(shù)重載
用 arguments 對象判斷傳遞給函數(shù)的參數(shù)個數(shù),即可模擬函數(shù)重載:
function doAdd() {
if(arguments.length == 1) { //arguments.length用于判斷參數(shù)的個數(shù)
alert(arguments[0] + 5);
} else if(arguments.length == 2) {
alert(arguments[0] + arguments[1]);
}
}
doAdd(10); //輸出 "15"
doAdd(40, 20); //輸出 "60"
三、ECMAScript Function 對象(類)
ECMAScript 的函數(shù)實際上是功能完整的對象。
1、Function 對象(類)
ECMAScript 最令人感興趣的可能莫過于函數(shù)實際上是功能完整的對象。
Function 類可以表示開發(fā)者定義的任何函數(shù)。
用 Function 類直接創(chuàng)建函數(shù)的語法如下:
var function_name = new function(arg1, arg2, ..., argN, function_body)
在上面的形式中,每個 arg 都是一個參數(shù),最后一個參數(shù)是函數(shù)主體(要執(zhí)行的代碼)。這些參數(shù)必須是字符串。
實例:
var sayHi =
new Function("sName", "sMessage", "alert(\"Hello \" + sName + sMessage);");
2、Function 對象的 length 屬性
如前所述,函數(shù)屬于引用類型,所以它們也有屬性和方法。
ECMAScript 定義的屬性 length 聲明了函數(shù)期望的參數(shù)個數(shù)
ECMAScript 可以接受任意多個參數(shù)(最多 25 個)
3、Function 對象的方法
Function 對象也有與所有對象共享的 valueOf() 方法和 toString() 方法。這兩個方法返回的都是函數(shù)的源代碼,在調(diào)試時尤其有用。例如:
function doAdd(iNum) {
alert(iNum + 10);
}
document.write(doAdd.toString());
返回結(jié)果:
function doAdd(iNum) { alert(iNum + 10); }
四、ECMAScript 閉包(closure)
ECMAScript 最易讓人誤解的一點是,它支持閉包(closure)。
閉包,指的是詞法表示包括不被計算的變量的函數(shù),也就是說,函數(shù)可以使用函數(shù)之外定義的變量。
1、簡單的閉包實例
在 ECMAScript 中使用全局變量是一個簡單的閉包實例。請思考下面這段代碼:
var sMessage = "hello world";
function sayHelloWorld() {
alert(sMessage);
}
sayHelloWorld();
2、復(fù)雜的閉包實例
在一個函數(shù)中定義另一個會使閉包變得更加復(fù)雜。例如:
var iBaseNum = 10;
function addNum(iNum1, iNum2) {
function doAdd() {
return iNum1 + iNum2 + iBaseNum;
}
return doAdd();
}
這里要掌握的重要概念是,doAdd() 函數(shù)根本不接受參數(shù),它使用的值是從執(zhí)行環(huán)境中獲取的。
補充
五、變量對象(Variable Object)
1、介紹
大多數(shù)ECMAScript程序員應(yīng)該都知道變量與執(zhí)行上下文有密切關(guān)系:
var a = 10; // 全局上下文中的變量
(function () {
var b = 20; // function上下文中的局部變量
})();
alert(a); // 10
alert(b); // 全局變量 "b" 沒有聲明
并且,很多程序員也都知道,當(dāng)前ECMAScript規(guī)范指出獨立作用域只能通過“函數(shù)(function)”代碼類型的執(zhí)行上下文創(chuàng)建。也就是說,相對于C/C++來說,ECMAScript里的for循環(huán)并不能創(chuàng)建一個局部的上下文。
for (var k in {a: 1, b: 2}) {
alert(k);
}
alert(k); // 盡管循環(huán)已經(jīng)結(jié)束但變量k依然在當(dāng)前作用域
2、數(shù)據(jù)聲明
如果變量與執(zhí)行上下文相關(guān),那變量自己應(yīng)該知道它的數(shù)據(jù)存儲在哪里,并且知道如何訪問。這種機制稱為變量對象(variable object)。
變量對象(縮寫為VO)是一個與執(zhí)行上下文相關(guān)的特殊對象,它存儲著在上下文中聲明的以下內(nèi)容:
- 變量 (var, 變量聲明);
- 函數(shù)聲明 (FunctionDeclaration, 縮寫為FD);
- 函數(shù)的形參
參考資料
【1.ECMAScript 函數(shù)概述】http://www.w3school.com.cn/js/pro_js_functions.asp
【2.深入理解JavaScript系列(12):變量對象(Variable Object)】http://www.cnblogs.com/TomXu/archive/2012/01/16/2309728.html