函數對象和其他內部對象的關系
alert(typeof(Function))); alert(typeof(new Function())); alert(typeof(Array)); alert(typeof(Object)); alert(typeof(new Array())); alert(typeof(new Date())); alert(typeof(new Object()));
運行這段代碼可以發現:前面4條語句都會顯示“function”,而后面3條語句則顯示“object”,可見new一個function 實際上是返回一個函數。這與其他的對象有很大的不同。其他的類型Array、Object等都會通過new操作符返回一個普通對象。盡管函數本身也是一個 對象,但它與普通的對象還是有區別的,因為它同時也是對象構造器,也就是說,可以new一個函數來返回一個對象。所有typeof返回 “function”的對象都是函數對象。也稱這樣的對象為構造器(constructor),因而,所有的構造器都是對象,但不是所有的對象都是構造器。
既然函數本身也是一個對象,它們的類型是function,聯想到C++、Java等面向對象語言的類定義,可以猜測到Function類型的作用所在,那就是可以給函數對象本身定義一些方法和屬性,借助於函數的prototype對象,可以很方便地修改和擴充Function類型的定義,例如下面擴展了函數類型Function,為其增加了method1方法,作用是彈出對話框顯示"function":
Function.prototype.method1=function(){ alert("function"); } function func1(a,b,c){ return a+b+c; } func1.method1(); func1.method1.method1();
注意最后一個語句:func1.method1.mehotd1(),它調用了method1這個函數對象的method1方法。雖然看上去 有點容易混淆,但仔細觀察一下語法還是很明確的:這是一個遞歸的定義。因為method1本身也是一個函數,所以它同樣具有函數對象的屬性和方法,所有對 Function類型的方法擴充都具有這樣的遞歸性質。
Function是所有函數對象的基礎,而Object則是所有對象(包括函數對象)的基礎。在JavaScript中,任何一個對象都是 Object的實例,因此,可以修改Object這個類型來讓所有的對象具有一些通用的屬性和方法,修改Object類型是通過prototype來完成的:
Object.prototype.getType=function(){ return typeof(this); } var array1=new Array(); function func1(a,b){ return a+b; } alert(array1.getType()); alert(func1.getType());
上面的代碼為所有的對象添加了getType方法,作用是返回該對象的類型。兩條alert語句分別會顯示“object”和“function”。
將函數作為參數傳遞
在前面已經介紹了函數對象本質,每個函數都被表示為一個特殊的對象,可以方便的將其賦值給一個變量,再通過這個變量名進行函數調用。作為一個變量,它可以以參數的形式傳遞給另一個函數,這在前面介紹JavaScript事件處理機制中已經看到過這樣的用法,例如下面的程序將func1作為參數 傳遞給func2:
function func1(theFunc){ theFunc(); } function func2(){ alert("ok"); } func1(func2);
在最后一條語句中,func2作為一個對象傳遞給了func1的形參theFunc,再由func1內部進行theFunc的調用。事實上,將函數作為參數傳遞,或者是將函數賦值給其他變量是所有事件機制的基礎。
例如,如果需要在頁面載入時進行一些初始化工作,可以先定義一個init的初始化函數,再通過window.onload=init;語句將其綁定到頁面載入完成的事件。這里的init就是一個函數對象,它可以加入window的onload事件列表。
Function是javascript里最常用的一個概念,javascript里的function是最容易入手的一個功能,但它也是javascript最難理解最難掌握的一個概念。
今天我們來嘗試理解Function和Object.因為這個里面有些人前期可能會搞糊塗.他們之間到底是什么關系.當然也不除外當初的我.
注意:官方定義: 在Javascript中,每一個函數實際上都是一個函數對象.
我們先來看最簡單的兩個代碼,也是最容易理解的。
function fn(){} var obj = {} console.log(fn instanceof Function)//true console.log(obj instanceof Object)//true console.log(fn instanceof Object)//true console.log(obj instanceof Function)//false
前面兩個打印的效果,大家都容易理解。
后面 fn instanceof Object 是為true.這里也是一樣,從函數的定義來說: 在javascript中一切函數實際都是函數對象. 所以為true就不奇怪了
obj instanceof Function 為false,當然不奇怪了.因為他是一個對象,不是函數.
我們再來看一個代碼
console.log(Function instanceof Object); // true console.log(Object instanceof Function); // true
代碼很簡單.運行結構兩個都是為true,為什么呢? 第一個用函數的定義來說,(javascript中函數實際也是一個函數對象),當然為true,那第二個呢?對象也是函數?
Object也是函數.因為Object的結構是function Object(){native code}
這種形式,很清晰的就是聲明的一個Object函數,當然就是函數了,所以兩個都是為true.
他們兩個Function和Object函數實現代碼,那當然是不一樣了.他們是怎么實現的,那我們就不去詳細琢磨了,如果想琢磨的,就可以了解瀏覽器的相關知識了。