認識js函數對象(Function Object)


認識函數對象(Function Object)
可以用function關鍵字定義一個函數,對於每個函數可以為其指定一個函數名,通過函
數名來進行調用。這些都是代碼給用戶的印象,而在JavaScript解釋執行的時候,實際上每
個函數都是被維護為一個對象,這就是本小節將要介紹的函數對象(Function Object)。
函數對象與其它用戶所定義的對象有着本質的區別,這一類對象被稱之為內部對象,例
如日期對象(Date)、數組對象(Array)、字符串對象(String)都是屬於內部對象。換句話
說,這些內置對象的構造器是由JavaScript本身所定義的:通過執行new Array()這樣的語句
返回一個對象,JavaScript 內部有一套機制來初始化返回的對象,而不是由用戶來指定對象
的構造方式。
在 JavaScript中,函數對象對應的類型是Function,正如數組對象對應的類型是Array,
日期對象對應的類型是Date一樣,可以通過new Function()來創建一個函數對象,也可以通
過function關鍵字來創建一個對象。為了便於理解,將函數對象的創建和數組對象的創建來
比較。先看數組對象:下面兩行代碼的作用是一樣的,都是創建一個數組對象myArray:
var myArray=[];
//等價於
var myArray=new Array();
同樣,下面的兩段代碼也是等價的,都是創建一個函數myFunction:
function myFunction(a,b){
return a+b;
}
//等價於
var myFunction=new Function("a","b","return a+b");
現在上面的代碼還有些難以理解,但是通過和構造數組對象語句的比較,可以清楚的看
到函數的對象本質,前面介紹的函數聲明是上述代碼的第一種方式,而在解釋器內部,當遇
到這種語法時,就會自動構造一個Function 對象,將函數作為一個內部的對象來存儲和運
行。從這里也可以看到,一個函數對象名稱(函數變量)和一個普通變量名稱具有同樣的規
范,都可以通過變量名來引用這個變量,但是函數變量名后面可以跟上括號和參數列表來進
行函數調用。
也許不會有人通過new Function()的形式來創建一個函數,因為一個函數體通常會有多
條語句,如果將它們以一個字符串的形式作為參數傳遞,那么代碼的可讀性會非常的差。下
面介紹一下其使用語法:
var funcName=new Function(p1,p2,...,pn,body);
參數的類型都是字符串,p1 到pn表示所創建函數的參數名稱列表,body表示所創建函
數的函數體語句,而funcName就是所創建函數的名稱了。可以不指定任何參數創建一個空
函數,不指定funcName創建一個無名函數,當然那樣的函數什么用處都沒有。
需要注意的是,前面說p1 到pn是參數名稱的列表,這意味着p1不僅僅只能代表一個
參數,它也可以是一個逗號格開的參數列表,例如下面的定義是等價的:
new Function("a", "b", "c", "return a+b+c")
new Function("a, b, c", "return a+b+c")
new Function("a,b", "c", "return a+b+c")
JavaScript引入Function類型並提供new Function()這樣的語法來創建函數並不是毫無意
義的,在后面可以看到,函數作為一個對象,它本身就可以具有一些方法和屬性,而為函數
對象添加屬性和方法就必須借助於Function這個類型。
現在已經認識到了函數的本質,它其實是一個內部對象,由JavaScript解釋器決定其運
行方式。通過上述代碼創建的函數,在程序中可以使用函數名進行調用。於是在本節開頭列
出的函數定義問題也得到了解釋:它們都是創建函數對象的正確語法。注意直接在函數聲明
后面加上括號就表示創建完成后立即進行函數調用,例如:
var i=function (a,b){
return a+b;
}(1,2);
alert(i);
這段代碼會顯示變量i 的值等於3。i 是表示返回的值,而不是創建的函數,因為括號
“(”比等號“=”有更高的優先級。這樣的代碼可能並不常用,但當用戶想在很長的代碼段
中進行模塊化設計或者想避免命名沖突,這是一個不錯的解決辦法。
需要注意的是,盡管下面兩種創建函數的方法是等價的:
function funcName(){
//函數體
}
//等價於
var funcName=function(){
//函數體
}
但前面一種方式創建的是有名函數,而后面是創建了一個無名函數,只是讓一個變量指
向了這個無名函數。在使用上僅有一點區別,就是:對於有名函數,它可以出現在調用之后
再定義;而對於無名函數,它必須是在調用之前就已經定義。例如:
<script language="JavaScript" type="text/javascript">
<!--
func();
var func=function(){
alert(1)
}
//-->
</script>
這段語句將產生func未定義的錯誤,而:
<script language="JavaScript" type="text/javascript">
<!--
func();
function func(){
alert(1)
}
//-->
</script>
則能夠正確執行,甚至下面的語句也能正確執行:
<script language="JavaScript" type="text/javascript">
<!--
func();
var someFunc=function func(){
alert(1)
}
//-->
</script>
由此可見,盡管JavaScript是一門解釋型的語言,但它會在進行函數調用時,檢查整個
代碼中是否存在相應的函數定義,這個函數名只有是通過function funcName()形式定義的才
會有效,而不能是匿名函數。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM